/**
 * SimpleBar.js - v3.1.3
 * Scrollbars, simpler.
 * https://grsmto.github.io/simplebar/
 *
 * Made by Adrien Denat from a fork by Jonathan Nicol
 * Under MIT License
 */

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
        typeof define === 'function' && define.amd ? define(factory) :
            (global = global || self, global.SimpleBar = factory());
}(this, function () {
    'use strict';

    var _isObject = function (it) {
        return typeof it === 'object' ? it !== null : typeof it === 'function';
    };

    var _anObject = function (it) {
        if (!_isObject(it)) throw TypeError(it + ' is not an object!');
        return it;
    };

    // 7.2.1 RequireObjectCoercible(argument)
    var _defined = function (it) {
        if (it == undefined) throw TypeError("Can't call method on  " + it);
        return it;
    };

    // 7.1.13 ToObject(argument)

    var _toObject = function (it) {
        return Object(_defined(it));
    };

    // 7.1.4 ToInteger
    var ceil = Math.ceil;
    var floor = Math.floor;
    var _toInteger = function (it) {
        return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
    };

    // 7.1.15 ToLength

    var min = Math.min;
    var _toLength = function (it) {
        return it > 0 ? min(_toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
    };

    // true  -> String#at
    // false -> String#codePointAt
    var _stringAt = function (TO_STRING) {
        return function (that, pos) {
            var s = String(_defined(that));
            var i = _toInteger(pos);
            var l = s.length;
            var a, b;
            if (i < 0 || i >= l) return TO_STRING ? '' : undefined;
            a = s.charCodeAt(i);
            return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
                ? TO_STRING ? s.charAt(i) : a
                : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
        };
    };

    var at = _stringAt(true);

    // `AdvanceStringIndex` abstract operation
    // https://tc39.github.io/ecma262/#sec-advancestringindex
    var _advanceStringIndex = function (S, index, unicode) {
        return index + (unicode ? at(S, index).length : 1);
    };

    var toString = {}.toString;

    var _cof = function (it) {
        return toString.call(it).slice(8, -1);
    };

    var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

    function createCommonjsModule(fn, module) {
        return module = {exports: {}}, fn(module, module.exports), module.exports;
    }

    var _core = createCommonjsModule(function (module) {
        var core = module.exports = {version: '2.6.2'};
        if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
    });
    var _core_1 = _core.version;

    var _global = createCommonjsModule(function (module) {
        // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
        var global = module.exports = typeof window != 'undefined' && window.Math == Math
            ? window : typeof self != 'undefined' && self.Math == Math ? self
                // eslint-disable-next-line no-new-func
                : Function('return this')();
        if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef
    });

    var _library = false;

    var _shared = createCommonjsModule(function (module) {
        var SHARED = '__core-js_shared__';
        var store = _global[SHARED] || (_global[SHARED] = {});

        (module.exports = function (key, value) {
            return store[key] || (store[key] = value !== undefined ? value : {});
        })('versions', []).push({
            version: _core.version,
            mode: _library ? 'pure' : 'global',
            copyright: '© 2019 Denis Pushkarev (zloirock.ru)'
        });
    });

    var id = 0;
    var px = Math.random();
    var _uid = function (key) {
        return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
    };

    var _wks = createCommonjsModule(function (module) {
        var store = _shared('wks');

        var Symbol = _global.Symbol;
        var USE_SYMBOL = typeof Symbol == 'function';

        var $exports = module.exports = function (name) {
            return store[name] || (store[name] =
                USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : _uid)('Symbol.' + name));
        };

        $exports.store = store;
    });

    // getting tag from 19.1.3.6 Object.prototype.toString()

    var TAG = _wks('toStringTag');
    // ES3 wrong here
    var ARG = _cof(function () {
        return arguments;
    }()) == 'Arguments';

    // fallback for IE11 Script Access Denied error
    var tryGet = function (it, key) {
        try {
            return it[key];
        } catch (e) { /* empty */
        }
    };

    var _classof = function (it) {
        var O, T, B;
        return it === undefined ? 'Undefined' : it === null ? 'Null'
            // @@toStringTag case
            : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T
                // builtinTag case
                : ARG ? _cof(O)
                    // ES3 arguments fallback
                    : (B = _cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
    };

    var builtinExec = RegExp.prototype.exec;

    // `RegExpExec` abstract operation
    // https://tc39.github.io/ecma262/#sec-regexpexec
    var _regexpExecAbstract = function (R, S) {
        var exec = R.exec;
        if (typeof exec === 'function') {
            var result = exec.call(R, S);
            if (typeof result !== 'object') {
                throw new TypeError('RegExp exec method returned something other than an Object or null');
            }
            return result;
        }
        if (_classof(R) !== 'RegExp') {
            throw new TypeError('RegExp#exec called on incompatible receiver');
        }
        return builtinExec.call(R, S);
    };

    // 21.2.5.3 get RegExp.prototype.flags

    var _flags = function () {
        var that = _anObject(this);
        var result = '';
        if (that.global) result += 'g';
        if (that.ignoreCase) result += 'i';
        if (that.multiline) result += 'm';
        if (that.unicode) result += 'u';
        if (that.sticky) result += 'y';
        return result;
    };

    var nativeExec = RegExp.prototype.exec;
    // This always refers to the native implementation, because the
    // String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,
    // which loads this file before patching the method.
    var nativeReplace = String.prototype.replace;

    var patchedExec = nativeExec;

    var LAST_INDEX = 'lastIndex';

    var UPDATES_LAST_INDEX_WRONG = (function () {
        var re1 = /a/,
            re2 = /b*/g;
        nativeExec.call(re1, 'a');
        nativeExec.call(re2, 'a');
        return re1[LAST_INDEX] !== 0 || re2[LAST_INDEX] !== 0;
    })();

    // nonparticipating capturing group, copied from es5-shim's String#split patch.
    var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;

    var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;

    if (PATCH) {
        patchedExec = function exec(str) {
            var re = this;
            var lastIndex, reCopy, match, i;

            if (NPCG_INCLUDED) {
                reCopy = new RegExp('^' + re.source + '$(?!\\s)', _flags.call(re));
            }
            if (UPDATES_LAST_INDEX_WRONG) lastIndex = re[LAST_INDEX];

            match = nativeExec.call(re, str);

            if (UPDATES_LAST_INDEX_WRONG && match) {
                re[LAST_INDEX] = re.global ? match.index + match[0].length : lastIndex;
            }
            if (NPCG_INCLUDED && match && match.length > 1) {
                // Fix browsers whose `exec` methods don't consistently return `undefined`
                // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
                // eslint-disable-next-line no-loop-func
                nativeReplace.call(match[0], reCopy, function () {
                    for (i = 1; i < arguments.length - 2; i++) {
                        if (arguments[i] === undefined) match[i] = undefined;
                    }
                });
            }

            return match;
        };
    }

    var _regexpExec = patchedExec;

    var _fails = function (exec) {
        try {
            return !!exec();
        } catch (e) {
            return true;
        }
    };

    // Thank's IE8 for his funny defineProperty
    var _descriptors = !_fails(function () {
        return Object.defineProperty({}, 'a', {
            get: function () {
                return 7;
            }
        }).a != 7;
    });

    var document$1 = _global.document;
    // typeof document.createElement is 'object' in old IE
    var is = _isObject(document$1) && _isObject(document$1.createElement);
    var _domCreate = function (it) {
        return is ? document$1.createElement(it) : {};
    };

    var _ie8DomDefine = !_descriptors && !_fails(function () {
        return Object.defineProperty(_domCreate('div'), 'a', {
            get: function () {
                return 7;
            }
        }).a != 7;
    });

    // 7.1.1 ToPrimitive(input [, PreferredType])

    // instead of the ES6 spec version, we didn't implement @@toPrimitive case
    // and the second argument - flag - preferred type is a string
    var _toPrimitive = function (it, S) {
        if (!_isObject(it)) return it;
        var fn, val;
        if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val;
        if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) return val;
        if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val;
        throw TypeError("Can't convert object to primitive value");
    };

    var dP = Object.defineProperty;

    var f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) {
        _anObject(O);
        P = _toPrimitive(P, true);
        _anObject(Attributes);
        if (_ie8DomDefine) try {
            return dP(O, P, Attributes);
        } catch (e) { /* empty */
        }
        if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
        if ('value' in Attributes) O[P] = Attributes.value;
        return O;
    };

    var _objectDp = {
        f: f
    };

    var _propertyDesc = function (bitmap, value) {
        return {
            enumerable: !(bitmap & 1),
            configurable: !(bitmap & 2),
            writable: !(bitmap & 4),
            value: value
        };
    };

    var _hide = _descriptors ? function (object, key, value) {
        return _objectDp.f(object, key, _propertyDesc(1, value));
    } : function (object, key, value) {
        object[key] = value;
        return object;
    };

    var hasOwnProperty = {}.hasOwnProperty;
    var _has = function (it, key) {
        return hasOwnProperty.call(it, key);
    };

    var _redefine = createCommonjsModule(function (module) {
        var SRC = _uid('src');
        var TO_STRING = 'toString';
        var $toString = Function[TO_STRING];
        var TPL = ('' + $toString).split(TO_STRING);

        _core.inspectSource = function (it) {
            return $toString.call(it);
        };

        (module.exports = function (O, key, val, safe) {
            var isFunction = typeof val == 'function';
            if (isFunction) _has(val, 'name') || _hide(val, 'name', key);
            if (O[key] === val) return;
            if (isFunction) _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
            if (O === _global) {
                O[key] = val;
            } else if (!safe) {
                delete O[key];
                _hide(O, key, val);
            } else if (O[key]) {
                O[key] = val;
            } else {
                _hide(O, key, val);
            }
            // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
        })(Function.prototype, TO_STRING, function toString() {
            return typeof this == 'function' && this[SRC] || $toString.call(this);
        });
    });

    var _aFunction = function (it) {
        if (typeof it != 'function') throw TypeError(it + ' is not a function!');
        return it;
    };

    // optional / simple context binding

    var _ctx = function (fn, that, length) {
        _aFunction(fn);
        if (that === undefined) return fn;
        switch (length) {
            case 1:
                return function (a) {
                    return fn.call(that, a);
                };
            case 2:
                return function (a, b) {
                    return fn.call(that, a, b);
                };
            case 3:
                return function (a, b, c) {
                    return fn.call(that, a, b, c);
                };
        }
        return function (/* ...args */) {
            return fn.apply(that, arguments);
        };
    };

    var PROTOTYPE = 'prototype';

    var $export = function (type, name, source) {
        var IS_FORCED = type & $export.F;
        var IS_GLOBAL = type & $export.G;
        var IS_STATIC = type & $export.S;
        var IS_PROTO = type & $export.P;
        var IS_BIND = type & $export.B;
        var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE];
        var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {});
        var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});
        var key, own, out, exp;
        if (IS_GLOBAL) source = name;
        for (key in source) {
            // contains in native
            own = !IS_FORCED && target && target[key] !== undefined;
            // export native or passed
            out = (own ? target : source)[key];
            // bind timers to global for call from export context
            exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out;
            // extend global
            if (target) _redefine(target, key, out, type & $export.U);
            // export
            if (exports[key] != out) _hide(exports, key, exp);
            if (IS_PROTO && expProto[key] != out) expProto[key] = out;
        }
    };
    _global.core = _core;
    // type bitmap
    $export.F = 1;   // forced
    $export.G = 2;   // global
    $export.S = 4;   // static
    $export.P = 8;   // proto
    $export.B = 16;  // bind
    $export.W = 32;  // wrap
    $export.U = 64;  // safe
    $export.R = 128; // real proto method for `library`
    var _export = $export;

    _export({
        target: 'RegExp',
        proto: true,
        forced: _regexpExec !== /./.exec
    }, {
        exec: _regexpExec
    });

    var SPECIES = _wks('species');

    var REPLACE_SUPPORTS_NAMED_GROUPS = !_fails(function () {
        // #replace needs built-in support for named groups.
        // #match works fine because it just return the exec results, even if it has
        // a "grops" property.
        var re = /./;
        re.exec = function () {
            var result = [];
            result.groups = {a: '7'};
            return result;
        };
        return ''.replace(re, '$<a>') !== '7';
    });

    var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = (function () {
        // Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
        var re = /(?:)/;
        var originalExec = re.exec;
        re.exec = function () {
            return originalExec.apply(this, arguments);
        };
        var result = 'ab'.split(re);
        return result.length === 2 && result[0] === 'a' && result[1] === 'b';
    })();

    var _fixReWks = function (KEY, length, exec) {
        var SYMBOL = _wks(KEY);

        var DELEGATES_TO_SYMBOL = !_fails(function () {
            // String methods call symbol-named RegEp methods
            var O = {};
            O[SYMBOL] = function () {
                return 7;
            };
            return ''[KEY](O) != 7;
        });

        var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL ? !_fails(function () {
            // Symbol-named RegExp methods call .exec
            var execCalled = false;
            var re = /a/;
            re.exec = function () {
                execCalled = true;
                return null;
            };
            if (KEY === 'split') {
                // RegExp[@@split] doesn't call the regex's exec method, but first creates
                // a new one. We need to return the patched regex when creating the new one.
                re.constructor = {};
                re.constructor[SPECIES] = function () {
                    return re;
                };
            }
            re[SYMBOL]('');
            return !execCalled;
        }) : undefined;

        if (
            !DELEGATES_TO_SYMBOL ||
            !DELEGATES_TO_EXEC ||
            (KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS) ||
            (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)
        ) {
            var nativeRegExpMethod = /./[SYMBOL];
            var fns = exec(
                _defined,
                SYMBOL,
                ''[KEY],
                function maybeCallNative(nativeMethod, regexp, str, arg2, forceStringMethod) {
                    if (regexp.exec === _regexpExec) {
                        if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
                            // The native String method already delegates to @@method (this
                            // polyfilled function), leasing to infinite recursion.
                            // We avoid it by directly calling the native @@method method.
                            return {done: true, value: nativeRegExpMethod.call(regexp, str, arg2)};
                        }
                        return {done: true, value: nativeMethod.call(str, regexp, arg2)};
                    }
                    return {done: false};
                }
            );
            var strfn = fns[0];
            var rxfn = fns[1];

            _redefine(String.prototype, KEY, strfn);
            _hide(RegExp.prototype, SYMBOL, length == 2
                // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
                // 21.2.5.11 RegExp.prototype[@@split](string, limit)
                ? function (string, arg) {
                    return rxfn.call(string, this, arg);
                }
                // 21.2.5.6 RegExp.prototype[@@match](string)
                // 21.2.5.9 RegExp.prototype[@@search](string)
                : function (string) {
                    return rxfn.call(string, this);
                }
            );
        }
    };

    var max = Math.max;
    var min$1 = Math.min;
    var floor$1 = Math.floor;
    var SUBSTITUTION_SYMBOLS = /\$([$&`']|\d\d?|<[^>]*>)/g;
    var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&`']|\d\d?)/g;

    var maybeToString = function (it) {
        return it === undefined ? it : String(it);
    };

    // @@replace logic
    _fixReWks('replace', 2, function (defined, REPLACE, $replace, maybeCallNative) {
        return [
            // `String.prototype.replace` method
            // https://tc39.github.io/ecma262/#sec-string.prototype.replace
            function replace(searchValue, replaceValue) {
                var O = defined(this);
                var fn = searchValue == undefined ? undefined : searchValue[REPLACE];
                return fn !== undefined
                    ? fn.call(searchValue, O, replaceValue)
                    : $replace.call(String(O), searchValue, replaceValue);
            },
            // `RegExp.prototype[@@replace]` method
            // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace
            function (regexp, replaceValue) {
                var res = maybeCallNative($replace, regexp, this, replaceValue);
                if (res.done) return res.value;

                var rx = _anObject(regexp);
                var S = String(this);
                var functionalReplace = typeof replaceValue === 'function';
                if (!functionalReplace) replaceValue = String(replaceValue);
                var global = rx.global;
                if (global) {
                    var fullUnicode = rx.unicode;
                    rx.lastIndex = 0;
                }
                var results = [];
                while (true) {
                    var result = _regexpExecAbstract(rx, S);
                    if (result === null) break;
                    results.push(result);
                    if (!global) break;
                    var matchStr = String(result[0]);
                    if (matchStr === '') rx.lastIndex = _advanceStringIndex(S, _toLength(rx.lastIndex), fullUnicode);
                }
                var accumulatedResult = '';
                var nextSourcePosition = 0;
                for (var i = 0; i < results.length; i++) {
                    result = results[i];
                    var matched = String(result[0]);
                    var position = max(min$1(_toInteger(result.index), S.length), 0);
                    var captures = [];
                    // NOTE: This is equivalent to
                    //   captures = result.slice(1).map(maybeToString)
                    // but for some reason `nativeSlice.call(result, 1, result.length)` (called in
                    // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and
                    // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.
                    for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));
                    var namedCaptures = result.groups;
                    if (functionalReplace) {
                        var replacerArgs = [matched].concat(captures, position, S);
                        if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
                        var replacement = String(replaceValue.apply(undefined, replacerArgs));
                    } else {
                        replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
                    }
                    if (position >= nextSourcePosition) {
                        accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
                        nextSourcePosition = position + matched.length;
                    }
                }
                return accumulatedResult + S.slice(nextSourcePosition);
            }
        ];

        // https://tc39.github.io/ecma262/#sec-getsubstitution
        function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {
            var tailPos = position + matched.length;
            var m = captures.length;
            var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
            if (namedCaptures !== undefined) {
                namedCaptures = _toObject(namedCaptures);
                symbols = SUBSTITUTION_SYMBOLS;
            }
            return $replace.call(replacement, symbols, function (match, ch) {
                var capture;
                switch (ch.charAt(0)) {
                    case '$':
                        return '$';
                    case '&':
                        return matched;
                    case '`':
                        return str.slice(0, position);
                    case "'":
                        return str.slice(tailPos);
                    case '<':
                        capture = namedCaptures[ch.slice(1, -1)];
                        break;
                    default: // \d\d?
                        var n = +ch;
                        if (n === 0) return match;
                        if (n > m) {
                            var f = floor$1(n / 10);
                            if (f === 0) return match;
                            if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
                            return match;
                        }
                        capture = captures[n - 1];
                }
                return capture === undefined ? '' : capture;
            });
        }
    });

    var dP$1 = _objectDp.f;
    var FProto = Function.prototype;
    var nameRE = /^\s*function ([^ (]*)/;
    var NAME = 'name';

    // 19.2.4.2 name
    NAME in FProto || _descriptors && dP$1(FProto, NAME, {
        configurable: true,
        get: function () {
            try {
                return ('' + this).match(nameRE)[1];
            } catch (e) {
                return '';
            }
        }
    });

    // @@match logic
    _fixReWks('match', 1, function (defined, MATCH, $match, maybeCallNative) {
        return [
            // `String.prototype.match` method
            // https://tc39.github.io/ecma262/#sec-string.prototype.match
            function match(regexp) {
                var O = defined(this);
                var fn = regexp == undefined ? undefined : regexp[MATCH];
                return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
            },
            // `RegExp.prototype[@@match]` method
            // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@match
            function (regexp) {
                var res = maybeCallNative($match, regexp, this);
                if (res.done) return res.value;
                var rx = _anObject(regexp);
                var S = String(this);
                if (!rx.global) return _regexpExecAbstract(rx, S);
                var fullUnicode = rx.unicode;
                rx.lastIndex = 0;
                var A = [];
                var n = 0;
                var result;
                while ((result = _regexpExecAbstract(rx, S)) !== null) {
                    var matchStr = String(result[0]);
                    A[n] = matchStr;
                    if (matchStr === '') rx.lastIndex = _advanceStringIndex(S, _toLength(rx.lastIndex), fullUnicode);
                    n++;
                }
                return n === 0 ? null : A;
            }
        ];
    });

    // 22.1.3.31 Array.prototype[@@unscopables]
    var UNSCOPABLES = _wks('unscopables');
    var ArrayProto = Array.prototype;
    if (ArrayProto[UNSCOPABLES] == undefined) _hide(ArrayProto, UNSCOPABLES, {});
    var _addToUnscopables = function (key) {
        ArrayProto[UNSCOPABLES][key] = true;
    };

    var _iterStep = function (done, value) {
        return {value: value, done: !!done};
    };

    var _iterators = {};

    // fallback for non-array-like ES3 and non-enumerable old V8 strings

    // eslint-disable-next-line no-prototype-builtins
    var _iobject = Object('z').propertyIsEnumerable(0) ? Object : function (it) {
        return _cof(it) == 'String' ? it.split('') : Object(it);
    };

    // to indexed object, toObject with fallback for non-array-like ES3 strings


    var _toIobject = function (it) {
        return _iobject(_defined(it));
    };

    var max$1 = Math.max;
    var min$2 = Math.min;
    var _toAbsoluteIndex = function (index, length) {
        index = _toInteger(index);
        return index < 0 ? max$1(index + length, 0) : min$2(index, length);
    };

    // false -> Array#indexOf
    // true  -> Array#includes


    var _arrayIncludes = function (IS_INCLUDES) {
        return function ($this, el, fromIndex) {
            var O = _toIobject($this);
            var length = _toLength(O.length);
            var index = _toAbsoluteIndex(fromIndex, length);
            var value;
            // Array#includes uses SameValueZero equality algorithm
            // eslint-disable-next-line no-self-compare
            if (IS_INCLUDES && el != el) while (length > index) {
                value = O[index++];
                // eslint-disable-next-line no-self-compare
                if (value != value) return true;
                // Array#indexOf ignores holes, Array#includes - not
            } else for (; length > index; index++) if (IS_INCLUDES || index in O) {
                if (O[index] === el) return IS_INCLUDES || index || 0;
            }
            return !IS_INCLUDES && -1;
        };
    };

    var shared = _shared('keys');

    var _sharedKey = function (key) {
        return shared[key] || (shared[key] = _uid(key));
    };

    var arrayIndexOf = _arrayIncludes(false);
    var IE_PROTO = _sharedKey('IE_PROTO');

    var _objectKeysInternal = function (object, names) {
        var O = _toIobject(object);
        var i = 0;
        var result = [];
        var key;
        for (key in O) if (key != IE_PROTO) _has(O, key) && result.push(key);
        // Don't enum bug & hidden keys
        while (names.length > i) if (_has(O, key = names[i++])) {
            ~arrayIndexOf(result, key) || result.push(key);
        }
        return result;
    };

    // IE 8- don't enum bug keys
    var _enumBugKeys = (
        'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'
    ).split(',');

    // 19.1.2.14 / 15.2.3.14 Object.keys(O)


    var _objectKeys = Object.keys || function keys(O) {
        return _objectKeysInternal(O, _enumBugKeys);
    };

    var _objectDps = _descriptors ? Object.defineProperties : function defineProperties(O, Properties) {
        _anObject(O);
        var keys = _objectKeys(Properties);
        var length = keys.length;
        var i = 0;
        var P;
        while (length > i) _objectDp.f(O, P = keys[i++], Properties[P]);
        return O;
    };

    var document$2 = _global.document;
    var _html = document$2 && document$2.documentElement;

    // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])


    var IE_PROTO$1 = _sharedKey('IE_PROTO');
    var Empty = function () { /* empty */
    };
    var PROTOTYPE$1 = 'prototype';

    // Create object with fake `null` prototype: use iframe Object with cleared prototype
    var createDict = function () {
        // Thrash, waste and sodomy: IE GC bug
        var iframe = _domCreate('iframe');
        var i = _enumBugKeys.length;
        var lt = '<';
        var gt = '>';
        var iframeDocument;
        iframe.style.display = 'none';
        _html.appendChild(iframe);
        iframe.src = 'javascript:'; // eslint-disable-line no-script-url
        // createDict = iframe.contentWindow.Object;
        // html.removeChild(iframe);
        iframeDocument = iframe.contentWindow.document;
        iframeDocument.open();
        iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
        iframeDocument.close();
        createDict = iframeDocument.F;
        while (i--) delete createDict[PROTOTYPE$1][_enumBugKeys[i]];
        return createDict();
    };

    var _objectCreate = Object.create || function create(O, Properties) {
        var result;
        if (O !== null) {
            Empty[PROTOTYPE$1] = _anObject(O);
            result = new Empty();
            Empty[PROTOTYPE$1] = null;
            // add "__proto__" for Object.getPrototypeOf polyfill
            result[IE_PROTO$1] = O;
        } else result = createDict();
        return Properties === undefined ? result : _objectDps(result, Properties);
    };

    var def = _objectDp.f;

    var TAG$1 = _wks('toStringTag');

    var _setToStringTag = function (it, tag, stat) {
        if (it && !_has(it = stat ? it : it.prototype, TAG$1)) def(it, TAG$1, {configurable: true, value: tag});
    };

    var IteratorPrototype = {};

    // 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
    _hide(IteratorPrototype, _wks('iterator'), function () {
        return this;
    });

    var _iterCreate = function (Constructor, NAME, next) {
        Constructor.prototype = _objectCreate(IteratorPrototype, {next: _propertyDesc(1, next)});
        _setToStringTag(Constructor, NAME + ' Iterator');
    };

    // 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)


    var IE_PROTO$2 = _sharedKey('IE_PROTO');
    var ObjectProto = Object.prototype;

    var _objectGpo = Object.getPrototypeOf || function (O) {
        O = _toObject(O);
        if (_has(O, IE_PROTO$2)) return O[IE_PROTO$2];
        if (typeof O.constructor == 'function' && O instanceof O.constructor) {
            return O.constructor.prototype;
        }
        return O instanceof Object ? ObjectProto : null;
    };

    var ITERATOR = _wks('iterator');
    var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`
    var FF_ITERATOR = '@@iterator';
    var KEYS = 'keys';
    var VALUES = 'values';

    var returnThis = function () {
        return this;
    };

    var _iterDefine = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {
        _iterCreate(Constructor, NAME, next);
        var getMethod = function (kind) {
            if (!BUGGY && kind in proto) return proto[kind];
            switch (kind) {
                case KEYS:
                    return function keys() {
                        return new Constructor(this, kind);
                    };
                case VALUES:
                    return function values() {
                        return new Constructor(this, kind);
                    };
            }
            return function entries() {
                return new Constructor(this, kind);
            };
        };
        var TAG = NAME + ' Iterator';
        var DEF_VALUES = DEFAULT == VALUES;
        var VALUES_BUG = false;
        var proto = Base.prototype;
        var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];
        var $default = $native || getMethod(DEFAULT);
        var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;
        var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;
        var methods, key, IteratorPrototype;
        // Fix native
        if ($anyNative) {
            IteratorPrototype = _objectGpo($anyNative.call(new Base()));
            if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {
                // Set @@toStringTag to native iterators
                _setToStringTag(IteratorPrototype, TAG, true);
                // fix for some old engines
                if (!_library && typeof IteratorPrototype[ITERATOR] != 'function') _hide(IteratorPrototype, ITERATOR, returnThis);
            }
        }
        // fix Array#{values, @@iterator}.name in V8 / FF
        if (DEF_VALUES && $native && $native.name !== VALUES) {
            VALUES_BUG = true;
            $default = function values() {
                return $native.call(this);
            };
        }
        // Define iterator
        if ((!_library || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {
            _hide(proto, ITERATOR, $default);
        }
        // Plug for library
        _iterators[NAME] = $default;
        _iterators[TAG] = returnThis;
        if (DEFAULT) {
            methods = {
                values: DEF_VALUES ? $default : getMethod(VALUES),
                keys: IS_SET ? $default : getMethod(KEYS),
                entries: $entries
            };
            if (FORCED) for (key in methods) {
                if (!(key in proto)) _redefine(proto, key, methods[key]);
            } else _export(_export.P + _export.F * (BUGGY || VALUES_BUG), NAME, methods);
        }
        return methods;
    };

    // 22.1.3.4 Array.prototype.entries()
    // 22.1.3.13 Array.prototype.keys()
    // 22.1.3.29 Array.prototype.values()
    // 22.1.3.30 Array.prototype[@@iterator]()
    var es6_array_iterator = _iterDefine(Array, 'Array', function (iterated, kind) {
        this._t = _toIobject(iterated); // target
        this._i = 0;                   // next index
        this._k = kind;                // kind
        // 22.1.5.2.1 %ArrayIteratorPrototype%.next()
    }, function () {
        var O = this._t;
        var kind = this._k;
        var index = this._i++;
        if (!O || index >= O.length) {
            this._t = undefined;
            return _iterStep(1);
        }
        if (kind == 'keys') return _iterStep(0, index);
        if (kind == 'values') return _iterStep(0, O[index]);
        return _iterStep(0, [index, O[index]]);
    }, 'values');

    // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
    _iterators.Arguments = _iterators.Array;

    _addToUnscopables('keys');
    _addToUnscopables('values');
    _addToUnscopables('entries');

    var ITERATOR$1 = _wks('iterator');
    var TO_STRING_TAG = _wks('toStringTag');
    var ArrayValues = _iterators.Array;

    var DOMIterables = {
        CSSRuleList: true, // TODO: Not spec compliant, should be false.
        CSSStyleDeclaration: false,
        CSSValueList: false,
        ClientRectList: false,
        DOMRectList: false,
        DOMStringList: false,
        DOMTokenList: true,
        DataTransferItemList: false,
        FileList: false,
        HTMLAllCollection: false,
        HTMLCollection: false,
        HTMLFormElement: false,
        HTMLSelectElement: false,
        MediaList: true, // TODO: Not spec compliant, should be false.
        MimeTypeArray: false,
        NamedNodeMap: false,
        NodeList: true,
        PaintRequestList: false,
        Plugin: false,
        PluginArray: false,
        SVGLengthList: false,
        SVGNumberList: false,
        SVGPathSegList: false,
        SVGPointList: false,
        SVGStringList: false,
        SVGTransformList: false,
        SourceBufferList: false,
        StyleSheetList: true, // TODO: Not spec compliant, should be false.
        TextTrackCueList: false,
        TextTrackList: false,
        TouchList: false
    };

    for (var collections = _objectKeys(DOMIterables), i = 0; i < collections.length; i++) {
        var NAME$1 = collections[i];
        var explicit = DOMIterables[NAME$1];
        var Collection = _global[NAME$1];
        var proto = Collection && Collection.prototype;
        var key;
        if (proto) {
            if (!proto[ITERATOR$1]) _hide(proto, ITERATOR$1, ArrayValues);
            if (!proto[TO_STRING_TAG]) _hide(proto, TO_STRING_TAG, NAME$1);
            _iterators[NAME$1] = ArrayValues;
            if (explicit) for (key in es6_array_iterator) if (!proto[key]) _redefine(proto, key, es6_array_iterator[key], true);
        }
    }

    var $at = _stringAt(true);

    // 21.1.3.27 String.prototype[@@iterator]()
    _iterDefine(String, 'String', function (iterated) {
        this._t = String(iterated); // target
        this._i = 0;                // next index
        // 21.1.5.2.1 %StringIteratorPrototype%.next()
    }, function () {
        var O = this._t;
        var index = this._i;
        var point;
        if (index >= O.length) return {value: undefined, done: true};
        point = $at(O, index);
        this._i += point.length;
        return {value: point, done: false};
    });

    // call something on iterator step with safe closing on error

    var _iterCall = function (iterator, fn, value, entries) {
        try {
            return entries ? fn(_anObject(value)[0], value[1]) : fn(value);
            // 7.4.6 IteratorClose(iterator, completion)
        } catch (e) {
            var ret = iterator['return'];
            if (ret !== undefined) _anObject(ret.call(iterator));
            throw e;
        }
    };

    // check on default Array iterator

    var ITERATOR$2 = _wks('iterator');
    var ArrayProto$1 = Array.prototype;

    var _isArrayIter = function (it) {
        return it !== undefined && (_iterators.Array === it || ArrayProto$1[ITERATOR$2] === it);
    };

    var _createProperty = function (object, index, value) {
        if (index in object) _objectDp.f(object, index, _propertyDesc(0, value));
        else object[index] = value;
    };

    var ITERATOR$3 = _wks('iterator');

    var core_getIteratorMethod = _core.getIteratorMethod = function (it) {
        if (it != undefined) return it[ITERATOR$3]
            || it['@@iterator']
            || _iterators[_classof(it)];
    };

    var ITERATOR$4 = _wks('iterator');
    var SAFE_CLOSING = false;

    try {
        var riter = [7][ITERATOR$4]();
        riter['return'] = function () {
            SAFE_CLOSING = true;
        };
    } catch (e) { /* empty */
    }

    var _iterDetect = function (exec, skipClosing) {
        if (!skipClosing && !SAFE_CLOSING) return false;
        var safe = false;
        try {
            var arr = [7];
            var iter = arr[ITERATOR$4]();
            iter.next = function () {
                return {done: safe = true};
            };
            arr[ITERATOR$4] = function () {
                return iter;
            };
            exec(arr);
        } catch (e) { /* empty */
        }
        return safe;
    };

    _export(_export.S + _export.F * !_iterDetect(function (iter) {
    }), 'Array', {
        // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)
        from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
            var O = _toObject(arrayLike);
            var C = typeof this == 'function' ? this : Array;
            var aLen = arguments.length;
            var mapfn = aLen > 1 ? arguments[1] : undefined;
            var mapping = mapfn !== undefined;
            var index = 0;
            var iterFn = core_getIteratorMethod(O);
            var length, result, step, iterator;
            if (mapping) mapfn = _ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);
            // if object isn't iterable or it's array with default iterator - use simple case
            if (iterFn != undefined && !(C == Array && _isArrayIter(iterFn))) {
                for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) {
                    _createProperty(result, index, mapping ? _iterCall(iterator, mapfn, [step.value, index], true) : step.value);
                }
            } else {
                length = _toLength(O.length);
                for (result = new C(length); length > index; index++) {
                    _createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
                }
            }
            result.length = index;
            return result;
        }
    });

    function _classCallCheck(instance, Constructor) {
        if (!(instance instanceof Constructor)) {
            throw new TypeError("Cannot call a class as a function");
        }
    }

    function _defineProperties(target, props) {
        for (var i = 0; i < props.length; i++) {
            var descriptor = props[i];
            descriptor.enumerable = descriptor.enumerable || false;
            descriptor.configurable = true;
            if ("value" in descriptor) descriptor.writable = true;
            Object.defineProperty(target, descriptor.key, descriptor);
        }
    }

    function _createClass(Constructor, protoProps, staticProps) {
        if (protoProps) _defineProperties(Constructor.prototype, protoProps);
        if (staticProps) _defineProperties(Constructor, staticProps);
        return Constructor;
    }

    function _defineProperty(obj, key, value) {
        if (key in obj) {
            Object.defineProperty(obj, key, {
                value: value,
                enumerable: true,
                configurable: true,
                writable: true
            });
        } else {
            obj[key] = value;
        }

        return obj;
    }

    function _objectSpread(target) {
        for (var i = 1; i < arguments.length; i++) {
            var source = arguments[i] != null ? arguments[i] : {};
            var ownKeys = Object.keys(source);

            if (typeof Object.getOwnPropertySymbols === 'function') {
                ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
                    return Object.getOwnPropertyDescriptor(source, sym).enumerable;
                }));
            }

            ownKeys.forEach(function (key) {
                _defineProperty(target, key, source[key]);
            });
        }

        return target;
    }

    var scrollbarWidth = createCommonjsModule(function (module, exports) {
        /*! scrollbarWidth.js v0.1.3 | felixexter | MIT | https://github.com/felixexter/scrollbarWidth */
        (function (root, factory) {
            {
                module.exports = factory();
            }
        }(commonjsGlobal, function () {

            function scrollbarWidth() {
                if (typeof document === 'undefined') {
                    return 0
                }

                var
                    body = document.body,
                    box = document.createElement('div'),
                    boxStyle = box.style,
                    width;

                boxStyle.position = 'absolute';
                boxStyle.top = boxStyle.left = '-9999px';
                boxStyle.width = boxStyle.height = '100px';
                boxStyle.overflow = 'scroll';

                body.appendChild(box);

                width = box.offsetWidth - box.clientWidth;

                body.removeChild(box);

                return width;
            }

            return scrollbarWidth;
        }));
    });

    /**
     * lodash (Custom Build) <https://lodash.com/>
     * Build: `lodash modularize exports="npm" -o ./`
     * Copyright jQuery Foundation and other contributors <https://jquery.org/>
     * Released under MIT license <https://lodash.com/license>
     * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
     * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
     */

    /** Used as the `TypeError` message for "Functions" methods. */
    var FUNC_ERROR_TEXT = 'Expected a function';

    /** Used as references for various `Number` constants. */
    var NAN = 0 / 0;

    /** `Object#toString` result references. */
    var symbolTag = '[object Symbol]';

    /** Used to match leading and trailing whitespace. */
    var reTrim = /^\s+|\s+$/g;

    /** Used to detect bad signed hexadecimal string values. */
    var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;

    /** Used to detect binary string values. */
    var reIsBinary = /^0b[01]+$/i;

    /** Used to detect octal string values. */
    var reIsOctal = /^0o[0-7]+$/i;

    /** Built-in method references without a dependency on `root`. */
    var freeParseInt = parseInt;

    /** Detect free variable `global` from Node.js. */
    var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;

    /** Detect free variable `self`. */
    var freeSelf = typeof self == 'object' && self && self.Object === Object && self;

    /** Used as a reference to the global object. */
    var root = freeGlobal || freeSelf || Function('return this')();

    /** Used for built-in method references. */
    var objectProto = Object.prototype;

    /**
     * Used to resolve the
     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
     * of values.
     */
    var objectToString = objectProto.toString;

    /* Built-in method references for those with the same name as other `lodash` methods. */
    var nativeMax = Math.max,
        nativeMin = Math.min;

    /**
     * Gets the timestamp of the number of milliseconds that have elapsed since
     * the Unix epoch (1 January 1970 00:00:00 UTC).
     *
     * @static
     * @memberOf _
     * @since 2.4.0
     * @category Date
     * @returns {number} Returns the timestamp.
     * @example
     *
     * _.defer(function(stamp) {
     *   console.log(_.now() - stamp);
     * }, _.now());
     * // => Logs the number of milliseconds it took for the deferred invocation.
     */
    var now = function () {
        return root.Date.now();
    };

    /**
     * Creates a debounced function that delays invoking `func` until after `wait`
     * milliseconds have elapsed since the last time the debounced function was
     * invoked. The debounced function comes with a `cancel` method to cancel
     * delayed `func` invocations and a `flush` method to immediately invoke them.
     * Provide `options` to indicate whether `func` should be invoked on the
     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
     * with the last arguments provided to the debounced function. Subsequent
     * calls to the debounced function return the result of the last `func`
     * invocation.
     *
     * **Note:** If `leading` and `trailing` options are `true`, `func` is
     * invoked on the trailing edge of the timeout only if the debounced function
     * is invoked more than once during the `wait` timeout.
     *
     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
     *
     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
     * for details over the differences between `_.debounce` and `_.throttle`.
     *
     * @static
     * @memberOf _
     * @since 0.1.0
     * @category Function
     * @param {Function} func The function to debounce.
     * @param {number} [wait=0] The number of milliseconds to delay.
     * @param {Object} [options={}] The options object.
     * @param {boolean} [options.leading=false]
     *  Specify invoking on the leading edge of the timeout.
     * @param {number} [options.maxWait]
     *  The maximum time `func` is allowed to be delayed before it's invoked.
     * @param {boolean} [options.trailing=true]
     *  Specify invoking on the trailing edge of the timeout.
     * @returns {Function} Returns the new debounced function.
     * @example
     *
     * // Avoid costly calculations while the window size is in flux.
     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
     *
     * // Invoke `sendMail` when clicked, debouncing subsequent calls.
     * jQuery(element).on('click', _.debounce(sendMail, 300, {
     *   'leading': true,
     *   'trailing': false
     * }));
     *
     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
     * var source = new EventSource('/stream');
     * jQuery(source).on('message', debounced);
     *
     * // Cancel the trailing debounced invocation.
     * jQuery(window).on('popstate', debounced.cancel);
     */
    function debounce(func, wait, options) {
        var lastArgs,
            lastThis,
            maxWait,
            result,
            timerId,
            lastCallTime,
            lastInvokeTime = 0,
            leading = false,
            maxing = false,
            trailing = true;

        if (typeof func != 'function') {
            throw new TypeError(FUNC_ERROR_TEXT);
        }
        wait = toNumber(wait) || 0;
        if (isObject(options)) {
            leading = !!options.leading;
            maxing = 'maxWait' in options;
            maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
            trailing = 'trailing' in options ? !!options.trailing : trailing;
        }

        function invokeFunc(time) {
            var args = lastArgs,
                thisArg = lastThis;

            lastArgs = lastThis = undefined;
            lastInvokeTime = time;
            result = func.apply(thisArg, args);
            return result;
        }

        function leadingEdge(time) {
            // Reset any `maxWait` timer.
            lastInvokeTime = time;
            // Start the timer for the trailing edge.
            timerId = setTimeout(timerExpired, wait);
            // Invoke the leading edge.
            return leading ? invokeFunc(time) : result;
        }

        function remainingWait(time) {
            var timeSinceLastCall = time - lastCallTime,
                timeSinceLastInvoke = time - lastInvokeTime,
                result = wait - timeSinceLastCall;

            return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
        }

        function shouldInvoke(time) {
            var timeSinceLastCall = time - lastCallTime,
                timeSinceLastInvoke = time - lastInvokeTime;

            // Either this is the first call, activity has stopped and we're at the
            // trailing edge, the system time has gone backwards and we're treating
            // it as the trailing edge, or we've hit the `maxWait` limit.
            return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
                (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
        }

        function timerExpired() {
            var time = now();
            if (shouldInvoke(time)) {
                return trailingEdge(time);
            }
            // Restart the timer.
            timerId = setTimeout(timerExpired, remainingWait(time));
        }

        function trailingEdge(time) {
            timerId = undefined;

            // Only invoke if we have `lastArgs` which means `func` has been
            // debounced at least once.
            if (trailing && lastArgs) {
                return invokeFunc(time);
            }
            lastArgs = lastThis = undefined;
            return result;
        }

        function cancel() {
            if (timerId !== undefined) {
                clearTimeout(timerId);
            }
            lastInvokeTime = 0;
            lastArgs = lastCallTime = lastThis = timerId = undefined;
        }

        function flush() {
            return timerId === undefined ? result : trailingEdge(now());
        }

        function debounced() {
            var time = now(),
                isInvoking = shouldInvoke(time);

            lastArgs = arguments;
            lastThis = this;
            lastCallTime = time;

            if (isInvoking) {
                if (timerId === undefined) {
                    return leadingEdge(lastCallTime);
                }
                if (maxing) {
                    // Handle invocations in a tight loop.
                    timerId = setTimeout(timerExpired, wait);
                    return invokeFunc(lastCallTime);
                }
            }
            if (timerId === undefined) {
                timerId = setTimeout(timerExpired, wait);
            }
            return result;
        }

        debounced.cancel = cancel;
        debounced.flush = flush;
        return debounced;
    }

    /**
     * Creates a throttled function that only invokes `func` at most once per
     * every `wait` milliseconds. The throttled function comes with a `cancel`
     * method to cancel delayed `func` invocations and a `flush` method to
     * immediately invoke them. Provide `options` to indicate whether `func`
     * should be invoked on the leading and/or trailing edge of the `wait`
     * timeout. The `func` is invoked with the last arguments provided to the
     * throttled function. Subsequent calls to the throttled function return the
     * result of the last `func` invocation.
     *
     * **Note:** If `leading` and `trailing` options are `true`, `func` is
     * invoked on the trailing edge of the timeout only if the throttled function
     * is invoked more than once during the `wait` timeout.
     *
     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
     *
     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
     * for details over the differences between `_.throttle` and `_.debounce`.
     *
     * @static
     * @memberOf _
     * @since 0.1.0
     * @category Function
     * @param {Function} func The function to throttle.
     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
     * @param {Object} [options={}] The options object.
     * @param {boolean} [options.leading=true]
     *  Specify invoking on the leading edge of the timeout.
     * @param {boolean} [options.trailing=true]
     *  Specify invoking on the trailing edge of the timeout.
     * @returns {Function} Returns the new throttled function.
     * @example
     *
     * // Avoid excessively updating the position while scrolling.
     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
     *
     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
     * jQuery(element).on('click', throttled);
     *
     * // Cancel the trailing throttled invocation.
     * jQuery(window).on('popstate', throttled.cancel);
     */
    function throttle(func, wait, options) {
        var leading = true,
            trailing = true;

        if (typeof func != 'function') {
            throw new TypeError(FUNC_ERROR_TEXT);
        }
        if (isObject(options)) {
            leading = 'leading' in options ? !!options.leading : leading;
            trailing = 'trailing' in options ? !!options.trailing : trailing;
        }
        return debounce(func, wait, {
            'leading': leading,
            'maxWait': wait,
            'trailing': trailing
        });
    }

    /**
     * Checks if `value` is the
     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
     *
     * @static
     * @memberOf _
     * @since 0.1.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
     * @example
     *
     * _.isObject({});
     * // => true
     *
     * _.isObject([1, 2, 3]);
     * // => true
     *
     * _.isObject(_.noop);
     * // => true
     *
     * _.isObject(null);
     * // => false
     */
    function isObject(value) {
        var type = typeof value;
        return !!value && (type == 'object' || type == 'function');
    }

    /**
     * Checks if `value` is object-like. A value is object-like if it's not `null`
     * and has a `typeof` result of "object".
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
     * @example
     *
     * _.isObjectLike({});
     * // => true
     *
     * _.isObjectLike([1, 2, 3]);
     * // => true
     *
     * _.isObjectLike(_.noop);
     * // => false
     *
     * _.isObjectLike(null);
     * // => false
     */
    function isObjectLike(value) {
        return !!value && typeof value == 'object';
    }

    /**
     * Checks if `value` is classified as a `Symbol` primitive or object.
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
     * @example
     *
     * _.isSymbol(Symbol.iterator);
     * // => true
     *
     * _.isSymbol('abc');
     * // => false
     */
    function isSymbol(value) {
        return typeof value == 'symbol' ||
            (isObjectLike(value) && objectToString.call(value) == symbolTag);
    }

    /**
     * Converts `value` to a number.
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to process.
     * @returns {number} Returns the number.
     * @example
     *
     * _.toNumber(3.2);
     * // => 3.2
     *
     * _.toNumber(Number.MIN_VALUE);
     * // => 5e-324
     *
     * _.toNumber(Infinity);
     * // => Infinity
     *
     * _.toNumber('3.2');
     * // => 3.2
     */
    function toNumber(value) {
        if (typeof value == 'number') {
            return value;
        }
        if (isSymbol(value)) {
            return NAN;
        }
        if (isObject(value)) {
            var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
            value = isObject(other) ? (other + '') : other;
        }
        if (typeof value != 'string') {
            return value === 0 ? value : +value;
        }
        value = value.replace(reTrim, '');
        var isBinary = reIsBinary.test(value);
        return (isBinary || reIsOctal.test(value))
            ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
            : (reIsBadHex.test(value) ? NAN : +value);
    }

    var lodash_throttle = throttle;

    /**
     * lodash (Custom Build) <https://lodash.com/>
     * Build: `lodash modularize exports="npm" -o ./`
     * Copyright jQuery Foundation and other contributors <https://jquery.org/>
     * Released under MIT license <https://lodash.com/license>
     * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
     * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
     */

    /** Used as the `TypeError` message for "Functions" methods. */
    var FUNC_ERROR_TEXT$1 = 'Expected a function';

    /** Used as references for various `Number` constants. */
    var NAN$1 = 0 / 0;

    /** `Object#toString` result references. */
    var symbolTag$1 = '[object Symbol]';

    /** Used to match leading and trailing whitespace. */
    var reTrim$1 = /^\s+|\s+$/g;

    /** Used to detect bad signed hexadecimal string values. */
    var reIsBadHex$1 = /^[-+]0x[0-9a-f]+$/i;

    /** Used to detect binary string values. */
    var reIsBinary$1 = /^0b[01]+$/i;

    /** Used to detect octal string values. */
    var reIsOctal$1 = /^0o[0-7]+$/i;

    /** Built-in method references without a dependency on `root`. */
    var freeParseInt$1 = parseInt;

    /** Detect free variable `global` from Node.js. */
    var freeGlobal$1 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;

    /** Detect free variable `self`. */
    var freeSelf$1 = typeof self == 'object' && self && self.Object === Object && self;

    /** Used as a reference to the global object. */
    var root$1 = freeGlobal$1 || freeSelf$1 || Function('return this')();

    /** Used for built-in method references. */
    var objectProto$1 = Object.prototype;

    /**
     * Used to resolve the
     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
     * of values.
     */
    var objectToString$1 = objectProto$1.toString;

    /* Built-in method references for those with the same name as other `lodash` methods. */
    var nativeMax$1 = Math.max,
        nativeMin$1 = Math.min;

    /**
     * Gets the timestamp of the number of milliseconds that have elapsed since
     * the Unix epoch (1 January 1970 00:00:00 UTC).
     *
     * @static
     * @memberOf _
     * @since 2.4.0
     * @category Date
     * @returns {number} Returns the timestamp.
     * @example
     *
     * _.defer(function(stamp) {
     *   console.log(_.now() - stamp);
     * }, _.now());
     * // => Logs the number of milliseconds it took for the deferred invocation.
     */
    var now$1 = function () {
        return root$1.Date.now();
    };

    /**
     * Creates a debounced function that delays invoking `func` until after `wait`
     * milliseconds have elapsed since the last time the debounced function was
     * invoked. The debounced function comes with a `cancel` method to cancel
     * delayed `func` invocations and a `flush` method to immediately invoke them.
     * Provide `options` to indicate whether `func` should be invoked on the
     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
     * with the last arguments provided to the debounced function. Subsequent
     * calls to the debounced function return the result of the last `func`
     * invocation.
     *
     * **Note:** If `leading` and `trailing` options are `true`, `func` is
     * invoked on the trailing edge of the timeout only if the debounced function
     * is invoked more than once during the `wait` timeout.
     *
     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
     *
     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
     * for details over the differences between `_.debounce` and `_.throttle`.
     *
     * @static
     * @memberOf _
     * @since 0.1.0
     * @category Function
     * @param {Function} func The function to debounce.
     * @param {number} [wait=0] The number of milliseconds to delay.
     * @param {Object} [options={}] The options object.
     * @param {boolean} [options.leading=false]
     *  Specify invoking on the leading edge of the timeout.
     * @param {number} [options.maxWait]
     *  The maximum time `func` is allowed to be delayed before it's invoked.
     * @param {boolean} [options.trailing=true]
     *  Specify invoking on the trailing edge of the timeout.
     * @returns {Function} Returns the new debounced function.
     * @example
     *
     * // Avoid costly calculations while the window size is in flux.
     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
     *
     * // Invoke `sendMail` when clicked, debouncing subsequent calls.
     * jQuery(element).on('click', _.debounce(sendMail, 300, {
     *   'leading': true,
     *   'trailing': false
     * }));
     *
     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
     * var source = new EventSource('/stream');
     * jQuery(source).on('message', debounced);
     *
     * // Cancel the trailing debounced invocation.
     * jQuery(window).on('popstate', debounced.cancel);
     */
    function debounce$1(func, wait, options) {
        var lastArgs,
            lastThis,
            maxWait,
            result,
            timerId,
            lastCallTime,
            lastInvokeTime = 0,
            leading = false,
            maxing = false,
            trailing = true;

        if (typeof func != 'function') {
            throw new TypeError(FUNC_ERROR_TEXT$1);
        }
        wait = toNumber$1(wait) || 0;
        if (isObject$1(options)) {
            leading = !!options.leading;
            maxing = 'maxWait' in options;
            maxWait = maxing ? nativeMax$1(toNumber$1(options.maxWait) || 0, wait) : maxWait;
            trailing = 'trailing' in options ? !!options.trailing : trailing;
        }

        function invokeFunc(time) {
            var args = lastArgs,
                thisArg = lastThis;

            lastArgs = lastThis = undefined;
            lastInvokeTime = time;
            result = func.apply(thisArg, args);
            return result;
        }

        function leadingEdge(time) {
            // Reset any `maxWait` timer.
            lastInvokeTime = time;
            // Start the timer for the trailing edge.
            timerId = setTimeout(timerExpired, wait);
            // Invoke the leading edge.
            return leading ? invokeFunc(time) : result;
        }

        function remainingWait(time) {
            var timeSinceLastCall = time - lastCallTime,
                timeSinceLastInvoke = time - lastInvokeTime,
                result = wait - timeSinceLastCall;

            return maxing ? nativeMin$1(result, maxWait - timeSinceLastInvoke) : result;
        }

        function shouldInvoke(time) {
            var timeSinceLastCall = time - lastCallTime,
                timeSinceLastInvoke = time - lastInvokeTime;

            // Either this is the first call, activity has stopped and we're at the
            // trailing edge, the system time has gone backwards and we're treating
            // it as the trailing edge, or we've hit the `maxWait` limit.
            return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
                (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
        }

        function timerExpired() {
            var time = now$1();
            if (shouldInvoke(time)) {
                return trailingEdge(time);
            }
            // Restart the timer.
            timerId = setTimeout(timerExpired, remainingWait(time));
        }

        function trailingEdge(time) {
            timerId = undefined;

            // Only invoke if we have `lastArgs` which means `func` has been
            // debounced at least once.
            if (trailing && lastArgs) {
                return invokeFunc(time);
            }
            lastArgs = lastThis = undefined;
            return result;
        }

        function cancel() {
            if (timerId !== undefined) {
                clearTimeout(timerId);
            }
            lastInvokeTime = 0;
            lastArgs = lastCallTime = lastThis = timerId = undefined;
        }

        function flush() {
            return timerId === undefined ? result : trailingEdge(now$1());
        }

        function debounced() {
            var time = now$1(),
                isInvoking = shouldInvoke(time);

            lastArgs = arguments;
            lastThis = this;
            lastCallTime = time;

            if (isInvoking) {
                if (timerId === undefined) {
                    return leadingEdge(lastCallTime);
                }
                if (maxing) {
                    // Handle invocations in a tight loop.
                    timerId = setTimeout(timerExpired, wait);
                    return invokeFunc(lastCallTime);
                }
            }
            if (timerId === undefined) {
                timerId = setTimeout(timerExpired, wait);
            }
            return result;
        }

        debounced.cancel = cancel;
        debounced.flush = flush;
        return debounced;
    }

    /**
     * Checks if `value` is the
     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
     *
     * @static
     * @memberOf _
     * @since 0.1.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
     * @example
     *
     * _.isObject({});
     * // => true
     *
     * _.isObject([1, 2, 3]);
     * // => true
     *
     * _.isObject(_.noop);
     * // => true
     *
     * _.isObject(null);
     * // => false
     */
    function isObject$1(value) {
        var type = typeof value;
        return !!value && (type == 'object' || type == 'function');
    }

    /**
     * Checks if `value` is object-like. A value is object-like if it's not `null`
     * and has a `typeof` result of "object".
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
     * @example
     *
     * _.isObjectLike({});
     * // => true
     *
     * _.isObjectLike([1, 2, 3]);
     * // => true
     *
     * _.isObjectLike(_.noop);
     * // => false
     *
     * _.isObjectLike(null);
     * // => false
     */
    function isObjectLike$1(value) {
        return !!value && typeof value == 'object';
    }

    /**
     * Checks if `value` is classified as a `Symbol` primitive or object.
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
     * @example
     *
     * _.isSymbol(Symbol.iterator);
     * // => true
     *
     * _.isSymbol('abc');
     * // => false
     */
    function isSymbol$1(value) {
        return typeof value == 'symbol' ||
            (isObjectLike$1(value) && objectToString$1.call(value) == symbolTag$1);
    }

    /**
     * Converts `value` to a number.
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to process.
     * @returns {number} Returns the number.
     * @example
     *
     * _.toNumber(3.2);
     * // => 3.2
     *
     * _.toNumber(Number.MIN_VALUE);
     * // => 5e-324
     *
     * _.toNumber(Infinity);
     * // => Infinity
     *
     * _.toNumber('3.2');
     * // => 3.2
     */
    function toNumber$1(value) {
        if (typeof value == 'number') {
            return value;
        }
        if (isSymbol$1(value)) {
            return NAN$1;
        }
        if (isObject$1(value)) {
            var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
            value = isObject$1(other) ? (other + '') : other;
        }
        if (typeof value != 'string') {
            return value === 0 ? value : +value;
        }
        value = value.replace(reTrim$1, '');
        var isBinary = reIsBinary$1.test(value);
        return (isBinary || reIsOctal$1.test(value))
            ? freeParseInt$1(value.slice(2), isBinary ? 2 : 8)
            : (reIsBadHex$1.test(value) ? NAN$1 : +value);
    }

    var lodash_debounce = debounce$1;

    /**
     * lodash (Custom Build) <https://lodash.com/>
     * Build: `lodash modularize exports="npm" -o ./`
     * Copyright jQuery Foundation and other contributors <https://jquery.org/>
     * Released under MIT license <https://lodash.com/license>
     * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
     * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
     */

    /** Used as the `TypeError` message for "Functions" methods. */
    var FUNC_ERROR_TEXT$2 = 'Expected a function';

    /** Used to stand-in for `undefined` hash values. */
    var HASH_UNDEFINED = '__lodash_hash_undefined__';

    /** `Object#toString` result references. */
    var funcTag = '[object Function]',
        genTag = '[object GeneratorFunction]';

    /**
     * Used to match `RegExp`
     * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
     */
    var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;

    /** Used to detect host constructors (Safari). */
    var reIsHostCtor = /^\[object .+?Constructor\]$/;

    /** Detect free variable `global` from Node.js. */
    var freeGlobal$2 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;

    /** Detect free variable `self`. */
    var freeSelf$2 = typeof self == 'object' && self && self.Object === Object && self;

    /** Used as a reference to the global object. */
    var root$2 = freeGlobal$2 || freeSelf$2 || Function('return this')();

    /**
     * Gets the value at `key` of `object`.
     *
     * @private
     * @param {Object} [object] The object to query.
     * @param {string} key The key of the property to get.
     * @returns {*} Returns the property value.
     */
    function getValue(object, key) {
        return object == null ? undefined : object[key];
    }

    /**
     * Checks if `value` is a host object in IE < 9.
     *
     * @private
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
     */
    function isHostObject(value) {
        // Many host objects are `Object` objects that can coerce to strings
        // despite having improperly defined `toString` methods.
        var result = false;
        if (value != null && typeof value.toString != 'function') {
            try {
                result = !!(value + '');
            } catch (e) {
            }
        }
        return result;
    }

    /** Used for built-in method references. */
    var arrayProto = Array.prototype,
        funcProto = Function.prototype,
        objectProto$2 = Object.prototype;

    /** Used to detect overreaching core-js shims. */
    var coreJsData = root$2['__core-js_shared__'];

    /** Used to detect methods masquerading as native. */
    var maskSrcKey = (function () {
        var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
        return uid ? ('Symbol(src)_1.' + uid) : '';
    }());

    /** Used to resolve the decompiled source of functions. */
    var funcToString = funcProto.toString;

    /** Used to check objects for own properties. */
    var hasOwnProperty$1 = objectProto$2.hasOwnProperty;

    /**
     * Used to resolve the
     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
     * of values.
     */
    var objectToString$2 = objectProto$2.toString;

    /** Used to detect if a method is native. */
    var reIsNative = RegExp('^' +
        funcToString.call(hasOwnProperty$1).replace(reRegExpChar, '\\$&')
            .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
    );

    /** Built-in value references. */
    var splice = arrayProto.splice;

    /* Built-in method references that are verified to be native. */
    var Map$1 = getNative(root$2, 'Map'),
        nativeCreate = getNative(Object, 'create');

    /**
     * Creates a hash object.
     *
     * @private
     * @constructor
     * @param {Array} [entries] The key-value pairs to cache.
     */
    function Hash(entries) {
        var index = -1,
            length = entries ? entries.length : 0;

        this.clear();
        while (++index < length) {
            var entry = entries[index];
            this.set(entry[0], entry[1]);
        }
    }

    /**
     * Removes all key-value entries from the hash.
     *
     * @private
     * @name clear
     * @memberOf Hash
     */
    function hashClear() {
        this.__data__ = nativeCreate ? nativeCreate(null) : {};
    }

    /**
     * Removes `key` and its value from the hash.
     *
     * @private
     * @name delete
     * @memberOf Hash
     * @param {Object} hash The hash to modify.
     * @param {string} key The key of the value to remove.
     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
     */
    function hashDelete(key) {
        return this.has(key) && delete this.__data__[key];
    }

    /**
     * Gets the hash value for `key`.
     *
     * @private
     * @name get
     * @memberOf Hash
     * @param {string} key The key of the value to get.
     * @returns {*} Returns the entry value.
     */
    function hashGet(key) {
        var data = this.__data__;
        if (nativeCreate) {
            var result = data[key];
            return result === HASH_UNDEFINED ? undefined : result;
        }
        return hasOwnProperty$1.call(data, key) ? data[key] : undefined;
    }

    /**
     * Checks if a hash value for `key` exists.
     *
     * @private
     * @name has
     * @memberOf Hash
     * @param {string} key The key of the entry to check.
     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
     */
    function hashHas(key) {
        var data = this.__data__;
        return nativeCreate ? data[key] !== undefined : hasOwnProperty$1.call(data, key);
    }

    /**
     * Sets the hash `key` to `value`.
     *
     * @private
     * @name set
     * @memberOf Hash
     * @param {string} key The key of the value to set.
     * @param {*} value The value to set.
     * @returns {Object} Returns the hash instance.
     */
    function hashSet(key, value) {
        var data = this.__data__;
        data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
        return this;
    }

    // Add methods to `Hash`.
    Hash.prototype.clear = hashClear;
    Hash.prototype['delete'] = hashDelete;
    Hash.prototype.get = hashGet;
    Hash.prototype.has = hashHas;
    Hash.prototype.set = hashSet;

    /**
     * Creates an list cache object.
     *
     * @private
     * @constructor
     * @param {Array} [entries] The key-value pairs to cache.
     */
    function ListCache(entries) {
        var index = -1,
            length = entries ? entries.length : 0;

        this.clear();
        while (++index < length) {
            var entry = entries[index];
            this.set(entry[0], entry[1]);
        }
    }

    /**
     * Removes all key-value entries from the list cache.
     *
     * @private
     * @name clear
     * @memberOf ListCache
     */
    function listCacheClear() {
        this.__data__ = [];
    }

    /**
     * Removes `key` and its value from the list cache.
     *
     * @private
     * @name delete
     * @memberOf ListCache
     * @param {string} key The key of the value to remove.
     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
     */
    function listCacheDelete(key) {
        var data = this.__data__,
            index = assocIndexOf(data, key);

        if (index < 0) {
            return false;
        }
        var lastIndex = data.length - 1;
        if (index == lastIndex) {
            data.pop();
        } else {
            splice.call(data, index, 1);
        }
        return true;
    }

    /**
     * Gets the list cache value for `key`.
     *
     * @private
     * @name get
     * @memberOf ListCache
     * @param {string} key The key of the value to get.
     * @returns {*} Returns the entry value.
     */
    function listCacheGet(key) {
        var data = this.__data__,
            index = assocIndexOf(data, key);

        return index < 0 ? undefined : data[index][1];
    }

    /**
     * Checks if a list cache value for `key` exists.
     *
     * @private
     * @name has
     * @memberOf ListCache
     * @param {string} key The key of the entry to check.
     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
     */
    function listCacheHas(key) {
        return assocIndexOf(this.__data__, key) > -1;
    }

    /**
     * Sets the list cache `key` to `value`.
     *
     * @private
     * @name set
     * @memberOf ListCache
     * @param {string} key The key of the value to set.
     * @param {*} value The value to set.
     * @returns {Object} Returns the list cache instance.
     */
    function listCacheSet(key, value) {
        var data = this.__data__,
            index = assocIndexOf(data, key);

        if (index < 0) {
            data.push([key, value]);
        } else {
            data[index][1] = value;
        }
        return this;
    }

    // Add methods to `ListCache`.
    ListCache.prototype.clear = listCacheClear;
    ListCache.prototype['delete'] = listCacheDelete;
    ListCache.prototype.get = listCacheGet;
    ListCache.prototype.has = listCacheHas;
    ListCache.prototype.set = listCacheSet;

    /**
     * Creates a map cache object to store key-value pairs.
     *
     * @private
     * @constructor
     * @param {Array} [entries] The key-value pairs to cache.
     */
    function MapCache(entries) {
        var index = -1,
            length = entries ? entries.length : 0;

        this.clear();
        while (++index < length) {
            var entry = entries[index];
            this.set(entry[0], entry[1]);
        }
    }

    /**
     * Removes all key-value entries from the map.
     *
     * @private
     * @name clear
     * @memberOf MapCache
     */
    function mapCacheClear() {
        this.__data__ = {
            'hash': new Hash,
            'map': new (Map$1 || ListCache),
            'string': new Hash
        };
    }

    /**
     * Removes `key` and its value from the map.
     *
     * @private
     * @name delete
     * @memberOf MapCache
     * @param {string} key The key of the value to remove.
     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
     */
    function mapCacheDelete(key) {
        return getMapData(this, key)['delete'](key);
    }

    /**
     * Gets the map value for `key`.
     *
     * @private
     * @name get
     * @memberOf MapCache
     * @param {string} key The key of the value to get.
     * @returns {*} Returns the entry value.
     */
    function mapCacheGet(key) {
        return getMapData(this, key).get(key);
    }

    /**
     * Checks if a map value for `key` exists.
     *
     * @private
     * @name has
     * @memberOf MapCache
     * @param {string} key The key of the entry to check.
     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
     */
    function mapCacheHas(key) {
        return getMapData(this, key).has(key);
    }

    /**
     * Sets the map `key` to `value`.
     *
     * @private
     * @name set
     * @memberOf MapCache
     * @param {string} key The key of the value to set.
     * @param {*} value The value to set.
     * @returns {Object} Returns the map cache instance.
     */
    function mapCacheSet(key, value) {
        getMapData(this, key).set(key, value);
        return this;
    }

    // Add methods to `MapCache`.
    MapCache.prototype.clear = mapCacheClear;
    MapCache.prototype['delete'] = mapCacheDelete;
    MapCache.prototype.get = mapCacheGet;
    MapCache.prototype.has = mapCacheHas;
    MapCache.prototype.set = mapCacheSet;

    /**
     * Gets the index at which the `key` is found in `array` of key-value pairs.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {*} key The key to search for.
     * @returns {number} Returns the index of the matched value, else `-1`.
     */
    function assocIndexOf(array, key) {
        var length = array.length;
        while (length--) {
            if (eq(array[length][0], key)) {
                return length;
            }
        }
        return -1;
    }

    /**
     * The base implementation of `_.isNative` without bad shim checks.
     *
     * @private
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a native function,
     *  else `false`.
     */
    function baseIsNative(value) {
        if (!isObject$2(value) || isMasked(value)) {
            return false;
        }
        var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
        return pattern.test(toSource(value));
    }

    /**
     * Gets the data for `map`.
     *
     * @private
     * @param {Object} map The map to query.
     * @param {string} key The reference key.
     * @returns {*} Returns the map data.
     */
    function getMapData(map, key) {
        var data = map.__data__;
        return isKeyable(key)
            ? data[typeof key == 'string' ? 'string' : 'hash']
            : data.map;
    }

    /**
     * Gets the native function at `key` of `object`.
     *
     * @private
     * @param {Object} object The object to query.
     * @param {string} key The key of the method to get.
     * @returns {*} Returns the function if it's native, else `undefined`.
     */
    function getNative(object, key) {
        var value = getValue(object, key);
        return baseIsNative(value) ? value : undefined;
    }

    /**
     * Checks if `value` is suitable for use as unique object key.
     *
     * @private
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
     */
    function isKeyable(value) {
        var type = typeof value;
        return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
            ? (value !== '__proto__')
            : (value === null);
    }

    /**
     * Checks if `func` has its source masked.
     *
     * @private
     * @param {Function} func The function to check.
     * @returns {boolean} Returns `true` if `func` is masked, else `false`.
     */
    function isMasked(func) {
        return !!maskSrcKey && (maskSrcKey in func);
    }

    /**
     * Converts `func` to its source code.
     *
     * @private
     * @param {Function} func The function to process.
     * @returns {string} Returns the source code.
     */
    function toSource(func) {
        if (func != null) {
            try {
                return funcToString.call(func);
            } catch (e) {
            }
            try {
                return (func + '');
            } catch (e) {
            }
        }
        return '';
    }

    /**
     * Creates a function that memoizes the result of `func`. If `resolver` is
     * provided, it determines the cache key for storing the result based on the
     * arguments provided to the memoized function. By default, the first argument
     * provided to the memoized function is used as the map cache key. The `func`
     * is invoked with the `this` binding of the memoized function.
     *
     * **Note:** The cache is exposed as the `cache` property on the memoized
     * function. Its creation may be customized by replacing the `_.memoize.Cache`
     * constructor with one whose instances implement the
     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
     * method interface of `delete`, `get`, `has`, and `set`.
     *
     * @static
     * @memberOf _
     * @since 0.1.0
     * @category Function
     * @param {Function} func The function to have its output memoized.
     * @param {Function} [resolver] The function to resolve the cache key.
     * @returns {Function} Returns the new memoized function.
     * @example
     *
     * var object = { 'a': 1, 'b': 2 };
     * var other = { 'c': 3, 'd': 4 };
     *
     * var values = _.memoize(_.values);
     * values(object);
     * // => [1, 2]
     *
     * values(other);
     * // => [3, 4]
     *
     * object.a = 2;
     * values(object);
     * // => [1, 2]
     *
     * // Modify the result cache.
     * values.cache.set(object, ['a', 'b']);
     * values(object);
     * // => ['a', 'b']
     *
     * // Replace `_.memoize.Cache`.
     * _.memoize.Cache = WeakMap;
     */
    function memoize(func, resolver) {
        if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
            throw new TypeError(FUNC_ERROR_TEXT$2);
        }
        var memoized = function () {
            var args = arguments,
                key = resolver ? resolver.apply(this, args) : args[0],
                cache = memoized.cache;

            if (cache.has(key)) {
                return cache.get(key);
            }
            var result = func.apply(this, args);
            memoized.cache = cache.set(key, result);
            return result;
        };
        memoized.cache = new (memoize.Cache || MapCache);
        return memoized;
    }

    // Assign cache to `_.memoize`.
    memoize.Cache = MapCache;

    /**
     * Performs a
     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
     * comparison between two values to determine if they are equivalent.
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
     * @example
     *
     * var object = { 'a': 1 };
     * var other = { 'a': 1 };
     *
     * _.eq(object, object);
     * // => true
     *
     * _.eq(object, other);
     * // => false
     *
     * _.eq('a', 'a');
     * // => true
     *
     * _.eq('a', Object('a'));
     * // => false
     *
     * _.eq(NaN, NaN);
     * // => true
     */
    function eq(value, other) {
        return value === other || (value !== value && other !== other);
    }

    /**
     * Checks if `value` is classified as a `Function` object.
     *
     * @static
     * @memberOf _
     * @since 0.1.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a function, else `false`.
     * @example
     *
     * _.isFunction(_);
     * // => true
     *
     * _.isFunction(/abc/);
     * // => false
     */
    function isFunction(value) {
        // The use of `Object#toString` avoids issues with the `typeof` operator
        // in Safari 8-9 which returns 'object' for typed array and other constructors.
        var tag = isObject$2(value) ? objectToString$2.call(value) : '';
        return tag == funcTag || tag == genTag;
    }

    /**
     * Checks if `value` is the
     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
     *
     * @static
     * @memberOf _
     * @since 0.1.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
     * @example
     *
     * _.isObject({});
     * // => true
     *
     * _.isObject([1, 2, 3]);
     * // => true
     *
     * _.isObject(_.noop);
     * // => true
     *
     * _.isObject(null);
     * // => false
     */
    function isObject$2(value) {
        var type = typeof value;
        return !!value && (type == 'object' || type == 'function');
    }

    var lodash_memoize = memoize;

    /**
     * A collection of shims that provide minimal functionality of the ES6 collections.
     *
     * These implementations are not meant to be used outside of the ResizeObserver
     * modules as they cover only a limited range of use cases.
     */
    /* eslint-disable require-jsdoc, valid-jsdoc */
    var MapShim = (function () {
        if (typeof Map !== 'undefined') {
            return Map;
        }

        /**
         * Returns index in provided array that matches the specified key.
         *
         * @param {Array<Array>} arr
         * @param {*} key
         * @returns {number}
         */
        function getIndex(arr, key) {
            var result = -1;
            arr.some(function (entry, index) {
                if (entry[0] === key) {
                    result = index;
                    return true;
                }
                return false;
            });
            return result;
        }

        return /** @class */ (function () {
            function class_1() {
                this.__entries__ = [];
            }

            Object.defineProperty(class_1.prototype, "size", {
                /**
                 * @returns {boolean}
                 */
                get: function () {
                    return this.__entries__.length;
                },
                enumerable: true,
                configurable: true
            });
            /**
             * @param {*} key
             * @returns {*}
             */
            class_1.prototype.get = function (key) {
                var index = getIndex(this.__entries__, key);
                var entry = this.__entries__[index];
                return entry && entry[1];
            };
            /**
             * @param {*} key
             * @param {*} value
             * @returns {void}
             */
            class_1.prototype.set = function (key, value) {
                var index = getIndex(this.__entries__, key);
                if (~index) {
                    this.__entries__[index][1] = value;
                } else {
                    this.__entries__.push([key, value]);
                }
            };
            /**
             * @param {*} key
             * @returns {void}
             */
            class_1.prototype.delete = function (key) {
                var entries = this.__entries__;
                var index = getIndex(entries, key);
                if (~index) {
                    entries.splice(index, 1);
                }
            };
            /**
             * @param {*} key
             * @returns {void}
             */
            class_1.prototype.has = function (key) {
                return !!~getIndex(this.__entries__, key);
            };
            /**
             * @returns {void}
             */
            class_1.prototype.clear = function () {
                this.__entries__.splice(0);
            };
            /**
             * @param {Function} callback
             * @param {*} [ctx=null]
             * @returns {void}
             */
            class_1.prototype.forEach = function (callback, ctx) {
                if (ctx === void 0) {
                    ctx = null;
                }
                for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) {
                    var entry = _a[_i];
                    callback.call(ctx, entry[1], entry[0]);
                }
            };
            return class_1;
        }());
    })();

    /**
     * Detects whether window and document objects are available in current environment.
     */
    var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;

    // Returns global object of a current environment.
    var global$1 = (function () {
        if (typeof global !== 'undefined' && global.Math === Math) {
            return global;
        }
        if (typeof self !== 'undefined' && self.Math === Math) {
            return self;
        }
        if (typeof window !== 'undefined' && window.Math === Math) {
            return window;
        }
        // eslint-disable-next-line no-new-func
        return Function('return this')();
    })();

    /**
     * A shim for the requestAnimationFrame which falls back to the setTimeout if
     * first one is not supported.
     *
     * @returns {number} Requests' identifier.
     */
    var requestAnimationFrame$1 = (function () {
        if (typeof requestAnimationFrame === 'function') {
            // It's required to use a bounded function because IE sometimes throws
            // an "Invalid calling object" error if rAF is invoked without the global
            // object on the left hand side.
            return requestAnimationFrame.bind(global$1);
        }
        return function (callback) {
            return setTimeout(function () {
                return callback(Date.now());
            }, 1000 / 60);
        };
    })();

    // Defines minimum timeout before adding a trailing call.
    var trailingTimeout = 2;

    /**
     * Creates a wrapper function which ensures that provided callback will be
     * invoked only once during the specified delay period.
     *
     * @param {Function} callback - Function to be invoked after the delay period.
     * @param {number} delay - Delay after which to invoke callback.
     * @returns {Function}
     */
    function throttle$1(callback, delay) {
        var leadingCall = false, trailingCall = false, lastCallTime = 0;

        /**
         * Invokes the original callback function and schedules new invocation if
         * the "proxy" was called during current request.
         *
         * @returns {void}
         */
        function resolvePending() {
            if (leadingCall) {
                leadingCall = false;
                callback();
            }
            if (trailingCall) {
                proxy();
            }
        }

        /**
         * Callback invoked after the specified delay. It will further postpone
         * invocation of the original function delegating it to the
         * requestAnimationFrame.
         *
         * @returns {void}
         */
        function timeoutCallback() {
            requestAnimationFrame$1(resolvePending);
        }

        /**
         * Schedules invocation of the original function.
         *
         * @returns {void}
         */
        function proxy() {
            var timeStamp = Date.now();
            if (leadingCall) {
                // Reject immediately following calls.
                if (timeStamp - lastCallTime < trailingTimeout) {
                    return;
                }
                // Schedule new call to be in invoked when the pending one is resolved.
                // This is important for "transitions" which never actually start
                // immediately so there is a chance that we might miss one if change
                // happens amids the pending invocation.
                trailingCall = true;
            } else {
                leadingCall = true;
                trailingCall = false;
                setTimeout(timeoutCallback, delay);
            }
            lastCallTime = timeStamp;
        }

        return proxy;
    }

    // Minimum delay before invoking the update of observers.
    var REFRESH_DELAY = 20;
    // A list of substrings of CSS properties used to find transition events that
    // might affect dimensions of observed elements.
    var transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];
    // Check if MutationObserver is available.
    var mutationObserverSupported = typeof MutationObserver !== 'undefined';
    /**
     * Singleton controller class which handles updates of ResizeObserver instances.
     */
    var ResizeObserverController = /** @class */ (function () {
        /**
         * Creates a new instance of ResizeObserverController.
         *
         * @private
         */
        function ResizeObserverController() {
            /**
             * Indicates whether DOM listeners have been added.
             *
             * @private {boolean}
             */
            this.connected_ = false;
            /**
             * Tells that controller has subscribed for Mutation Events.
             *
             * @private {boolean}
             */
            this.mutationEventsAdded_ = false;
            /**
             * Keeps reference to the instance of MutationObserver.
             *
             * @private {MutationObserver}
             */
            this.mutationsObserver_ = null;
            /**
             * A list of connected observers.
             *
             * @private {Array<ResizeObserverSPI>}
             */
            this.observers_ = [];
            this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);
            this.refresh = throttle$1(this.refresh.bind(this), REFRESH_DELAY);
        }

        /**
         * Adds observer to observers list.
         *
         * @param {ResizeObserverSPI} observer - Observer to be added.
         * @returns {void}
         */
        ResizeObserverController.prototype.addObserver = function (observer) {
            if (!~this.observers_.indexOf(observer)) {
                this.observers_.push(observer);
            }
            // Add listeners if they haven't been added yet.
            if (!this.connected_) {
                this.connect_();
            }
        };
        /**
         * Removes observer from observers list.
         *
         * @param {ResizeObserverSPI} observer - Observer to be removed.
         * @returns {void}
         */
        ResizeObserverController.prototype.removeObserver = function (observer) {
            var observers = this.observers_;
            var index = observers.indexOf(observer);
            // Remove observer if it's present in registry.
            if (~index) {
                observers.splice(index, 1);
            }
            // Remove listeners if controller has no connected observers.
            if (!observers.length && this.connected_) {
                this.disconnect_();
            }
        };
        /**
         * Invokes the update of observers. It will continue running updates insofar
         * it detects changes.
         *
         * @returns {void}
         */
        ResizeObserverController.prototype.refresh = function () {
            var changesDetected = this.updateObservers_();
            // Continue running updates if changes have been detected as there might
            // be future ones caused by CSS transitions.
            if (changesDetected) {
                this.refresh();
            }
        };
        /**
         * Updates every observer from observers list and notifies them of queued
         * entries.
         *
         * @private
         * @returns {boolean} Returns "true" if any observer has detected changes in
         *      dimensions of it's elements.
         */
        ResizeObserverController.prototype.updateObservers_ = function () {
            // Collect observers that have active observations.
            var activeObservers = this.observers_.filter(function (observer) {
                return observer.gatherActive(), observer.hasActive();
            });
            // Deliver notifications in a separate cycle in order to avoid any
            // collisions between observers, e.g. when multiple instances of
            // ResizeObserver are tracking the same element and the callback of one
            // of them changes content dimensions of the observed target. Sometimes
            // this may result in notifications being blocked for the rest of observers.
            activeObservers.forEach(function (observer) {
                return observer.broadcastActive();
            });
            return activeObservers.length > 0;
        };
        /**
         * Initializes DOM listeners.
         *
         * @private
         * @returns {void}
         */
        ResizeObserverController.prototype.connect_ = function () {
            // Do nothing if running in a non-browser environment or if listeners
            // have been already added.
            if (!isBrowser || this.connected_) {
                return;
            }
            // Subscription to the "Transitionend" event is used as a workaround for
            // delayed transitions. This way it's possible to capture at least the
            // final state of an element.
            document.addEventListener('transitionend', this.onTransitionEnd_);
            window.addEventListener('resize', this.refresh);
            if (mutationObserverSupported) {
                this.mutationsObserver_ = new MutationObserver(this.refresh);
                this.mutationsObserver_.observe(document, {
                    attributes: true,
                    childList: true,
                    characterData: true,
                    subtree: true
                });
            } else {
                document.addEventListener('DOMSubtreeModified', this.refresh);
                this.mutationEventsAdded_ = true;
            }
            this.connected_ = true;
        };
        /**
         * Removes DOM listeners.
         *
         * @private
         * @returns {void}
         */
        ResizeObserverController.prototype.disconnect_ = function () {
            // Do nothing if running in a non-browser environment or if listeners
            // have been already removed.
            if (!isBrowser || !this.connected_) {
                return;
            }
            document.removeEventListener('transitionend', this.onTransitionEnd_);
            window.removeEventListener('resize', this.refresh);
            if (this.mutationsObserver_) {
                this.mutationsObserver_.disconnect();
            }
            if (this.mutationEventsAdded_) {
                document.removeEventListener('DOMSubtreeModified', this.refresh);
            }
            this.mutationsObserver_ = null;
            this.mutationEventsAdded_ = false;
            this.connected_ = false;
        };
        /**
         * "Transitionend" event handler.
         *
         * @private
         * @param {TransitionEvent} event
         * @returns {void}
         */
        ResizeObserverController.prototype.onTransitionEnd_ = function (_a) {
            var _b = _a.propertyName, propertyName = _b === void 0 ? '' : _b;
            // Detect whether transition may affect dimensions of an element.
            var isReflowProperty = transitionKeys.some(function (key) {
                return !!~propertyName.indexOf(key);
            });
            if (isReflowProperty) {
                this.refresh();
            }
        };
        /**
         * Returns instance of the ResizeObserverController.
         *
         * @returns {ResizeObserverController}
         */
        ResizeObserverController.getInstance = function () {
            if (!this.instance_) {
                this.instance_ = new ResizeObserverController();
            }
            return this.instance_;
        };
        /**
         * Holds reference to the controller's instance.
         *
         * @private {ResizeObserverController}
         */
        ResizeObserverController.instance_ = null;
        return ResizeObserverController;
    }());

    /**
     * Defines non-writable/enumerable properties of the provided target object.
     *
     * @param {Object} target - Object for which to define properties.
     * @param {Object} props - Properties to be defined.
     * @returns {Object} Target object.
     */
    var defineConfigurable = (function (target, props) {
        for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) {
            var key = _a[_i];
            Object.defineProperty(target, key, {
                value: props[key],
                enumerable: false,
                writable: false,
                configurable: true
            });
        }
        return target;
    });

    /**
     * Returns the global object associated with provided element.
     *
     * @param {Object} target
     * @returns {Object}
     */
    var getWindowOf = (function (target) {
        // Assume that the element is an instance of Node, which means that it
        // has the "ownerDocument" property from which we can retrieve a
        // corresponding global object.
        var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;
        // Return the local global object if it's not possible extract one from
        // provided element.
        return ownerGlobal || global$1;
    });

    // Placeholder of an empty content rectangle.
    var emptyRect = createRectInit(0, 0, 0, 0);

    /**
     * Converts provided string to a number.
     *
     * @param {number|string} value
     * @returns {number}
     */
    function toFloat(value) {
        return parseFloat(value) || 0;
    }

    /**
     * Extracts borders size from provided styles.
     *
     * @param {CSSStyleDeclaration} styles
     * @param {...string} positions - Borders positions (top, right, ...)
     * @returns {number}
     */
    function getBordersSize(styles) {
        var positions = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            positions[_i - 1] = arguments[_i];
        }
        return positions.reduce(function (size, position) {
            var value = styles['border-' + position + '-width'];
            return size + toFloat(value);
        }, 0);
    }

    /**
     * Extracts paddings sizes from provided styles.
     *
     * @param {CSSStyleDeclaration} styles
     * @returns {Object} Paddings box.
     */
    function getPaddings(styles) {
        var positions = ['top', 'right', 'bottom', 'left'];
        var paddings = {};
        for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {
            var position = positions_1[_i];
            var value = styles['padding-' + position];
            paddings[position] = toFloat(value);
        }
        return paddings;
    }

    /**
     * Calculates content rectangle of provided SVG element.
     *
     * @param {SVGGraphicsElement} target - Element content rectangle of which needs
     *      to be calculated.
     * @returns {DOMRectInit}
     */
    function getSVGContentRect(target) {
        var bbox = target.getBBox();
        return createRectInit(0, 0, bbox.width, bbox.height);
    }

    /**
     * Calculates content rectangle of provided HTMLElement.
     *
     * @param {HTMLElement} target - Element for which to calculate the content rectangle.
     * @returns {DOMRectInit}
     */
    function getHTMLElementContentRect(target) {
        // Client width & height properties can't be
        // used exclusively as they provide rounded values.
        var clientWidth = target.clientWidth, clientHeight = target.clientHeight;
        // By this condition we can catch all non-replaced inline, hidden and
        // detached elements. Though elements with width & height properties less
        // than 0.5 will be discarded as well.
        //
        // Without it we would need to implement separate methods for each of
        // those cases and it's not possible to perform a precise and performance
        // effective test for hidden elements. E.g. even jQuery's ':visible' filter
        // gives wrong results for elements with width & height less than 0.5.
        if (!clientWidth && !clientHeight) {
            return emptyRect;
        }
        var styles = getWindowOf(target).getComputedStyle(target);
        var paddings = getPaddings(styles);
        var horizPad = paddings.left + paddings.right;
        var vertPad = paddings.top + paddings.bottom;
        // Computed styles of width & height are being used because they are the
        // only dimensions available to JS that contain non-rounded values. It could
        // be possible to utilize the getBoundingClientRect if only it's data wasn't
        // affected by CSS transformations let alone paddings, borders and scroll bars.
        var width = toFloat(styles.width), height = toFloat(styles.height);
        // Width & height include paddings and borders when the 'border-box' box
        // model is applied (except for IE).
        if (styles.boxSizing === 'border-box') {
            // Following conditions are required to handle Internet Explorer which
            // doesn't include paddings and borders to computed CSS dimensions.
            //
            // We can say that if CSS dimensions + paddings are equal to the "client"
            // properties then it's either IE, and thus we don't need to subtract
            // anything, or an element merely doesn't have paddings/borders styles.
            if (Math.round(width + horizPad) !== clientWidth) {
                width -= getBordersSize(styles, 'left', 'right') + horizPad;
            }
            if (Math.round(height + vertPad) !== clientHeight) {
                height -= getBordersSize(styles, 'top', 'bottom') + vertPad;
            }
        }
        // Following steps can't be applied to the document's root element as its
        // client[Width/Height] properties represent viewport area of the window.
        // Besides, it's as well not necessary as the <html> itself neither has
        // rendered scroll bars nor it can be clipped.
        if (!isDocumentElement(target)) {
            // In some browsers (only in Firefox, actually) CSS width & height
            // include scroll bars size which can be removed at this step as scroll
            // bars are the only difference between rounded dimensions + paddings
            // and "client" properties, though that is not always true in Chrome.
            var vertScrollbar = Math.round(width + horizPad) - clientWidth;
            var horizScrollbar = Math.round(height + vertPad) - clientHeight;
            // Chrome has a rather weird rounding of "client" properties.
            // E.g. for an element with content width of 314.2px it sometimes gives
            // the client width of 315px and for the width of 314.7px it may give
            // 314px. And it doesn't happen all the time. So just ignore this delta
            // as a non-relevant.
            if (Math.abs(vertScrollbar) !== 1) {
                width -= vertScrollbar;
            }
            if (Math.abs(horizScrollbar) !== 1) {
                height -= horizScrollbar;
            }
        }
        return createRectInit(paddings.left, paddings.top, width, height);
    }

    /**
     * Checks whether provided element is an instance of the SVGGraphicsElement.
     *
     * @param {Element} target - Element to be checked.
     * @returns {boolean}
     */
    var isSVGGraphicsElement = (function () {
        // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement
        // interface.
        if (typeof SVGGraphicsElement !== 'undefined') {
            return function (target) {
                return target instanceof getWindowOf(target).SVGGraphicsElement;
            };
        }
        // If it's so, then check that element is at least an instance of the
        // SVGElement and that it has the "getBBox" method.
        // eslint-disable-next-line no-extra-parens
        return function (target) {
            return (target instanceof getWindowOf(target).SVGElement &&
                typeof target.getBBox === 'function');
        };
    })();

    /**
     * Checks whether provided element is a document element (<html>).
     *
     * @param {Element} target - Element to be checked.
     * @returns {boolean}
     */
    function isDocumentElement(target) {
        return target === getWindowOf(target).document.documentElement;
    }

    /**
     * Calculates an appropriate content rectangle for provided html or svg element.
     *
     * @param {Element} target - Element content rectangle of which needs to be calculated.
     * @returns {DOMRectInit}
     */
    function getContentRect(target) {
        if (!isBrowser) {
            return emptyRect;
        }
        if (isSVGGraphicsElement(target)) {
            return getSVGContentRect(target);
        }
        return getHTMLElementContentRect(target);
    }

    /**
     * Creates rectangle with an interface of the DOMRectReadOnly.
     * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly
     *
     * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.
     * @returns {DOMRectReadOnly}
     */
    function createReadOnlyRect(_a) {
        var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
        // If DOMRectReadOnly is available use it as a prototype for the rectangle.
        var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;
        var rect = Object.create(Constr.prototype);
        // Rectangle's properties are not writable and non-enumerable.
        defineConfigurable(rect, {
            x: x, y: y, width: width, height: height,
            top: y,
            right: x + width,
            bottom: height + y,
            left: x
        });
        return rect;
    }

    /**
     * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.
     * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit
     *
     * @param {number} x - X coordinate.
     * @param {number} y - Y coordinate.
     * @param {number} width - Rectangle's width.
     * @param {number} height - Rectangle's height.
     * @returns {DOMRectInit}
     */
    function createRectInit(x, y, width, height) {
        return {x: x, y: y, width: width, height: height};
    }

    /**
     * Class that is responsible for computations of the content rectangle of
     * provided DOM element and for keeping track of it's changes.
     */
    var ResizeObservation = /** @class */ (function () {
        /**
         * Creates an instance of ResizeObservation.
         *
         * @param {Element} target - Element to be observed.
         */
        function ResizeObservation(target) {
            /**
             * Broadcasted width of content rectangle.
             *
             * @type {number}
             */
            this.broadcastWidth = 0;
            /**
             * Broadcasted height of content rectangle.
             *
             * @type {number}
             */
            this.broadcastHeight = 0;
            /**
             * Reference to the last observed content rectangle.
             *
             * @private {DOMRectInit}
             */
            this.contentRect_ = createRectInit(0, 0, 0, 0);
            this.target = target;
        }

        /**
         * Updates content rectangle and tells whether it's width or height properties
         * have changed since the last broadcast.
         *
         * @returns {boolean}
         */
        ResizeObservation.prototype.isActive = function () {
            var rect = getContentRect(this.target);
            this.contentRect_ = rect;
            return (rect.width !== this.broadcastWidth ||
                rect.height !== this.broadcastHeight);
        };
        /**
         * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data
         * from the corresponding properties of the last observed content rectangle.
         *
         * @returns {DOMRectInit} Last observed content rectangle.
         */
        ResizeObservation.prototype.broadcastRect = function () {
            var rect = this.contentRect_;
            this.broadcastWidth = rect.width;
            this.broadcastHeight = rect.height;
            return rect;
        };
        return ResizeObservation;
    }());

    var ResizeObserverEntry = /** @class */ (function () {
        /**
         * Creates an instance of ResizeObserverEntry.
         *
         * @param {Element} target - Element that is being observed.
         * @param {DOMRectInit} rectInit - Data of the element's content rectangle.
         */
        function ResizeObserverEntry(target, rectInit) {
            var contentRect = createReadOnlyRect(rectInit);
            // According to the specification following properties are not writable
            // and are also not enumerable in the native implementation.
            //
            // Property accessors are not being used as they'd require to define a
            // private WeakMap storage which may cause memory leaks in browsers that
            // don't support this type of collections.
            defineConfigurable(this, {target: target, contentRect: contentRect});
        }

        return ResizeObserverEntry;
    }());

    var ResizeObserverSPI = /** @class */ (function () {
        /**
         * Creates a new instance of ResizeObserver.
         *
         * @param {ResizeObserverCallback} callback - Callback function that is invoked
         *      when one of the observed elements changes it's content dimensions.
         * @param {ResizeObserverController} controller - Controller instance which
         *      is responsible for the updates of observer.
         * @param {ResizeObserver} callbackCtx - Reference to the public
         *      ResizeObserver instance which will be passed to callback function.
         */
        function ResizeObserverSPI(callback, controller, callbackCtx) {
            /**
             * Collection of resize observations that have detected changes in dimensions
             * of elements.
             *
             * @private {Array<ResizeObservation>}
             */
            this.activeObservations_ = [];
            /**
             * Registry of the ResizeObservation instances.
             *
             * @private {Map<Element, ResizeObservation>}
             */
            this.observations_ = new MapShim();
            if (typeof callback !== 'function') {
                throw new TypeError('The callback provided as parameter 1 is not a function.');
            }
            this.callback_ = callback;
            this.controller_ = controller;
            this.callbackCtx_ = callbackCtx;
        }

        /**
         * Starts observing provided element.
         *
         * @param {Element} target - Element to be observed.
         * @returns {void}
         */
        ResizeObserverSPI.prototype.observe = function (target) {
            if (!arguments.length) {
                throw new TypeError('1 argument required, but only 0 present.');
            }
            // Do nothing if current environment doesn't have the Element interface.
            if (typeof Element === 'undefined' || !(Element instanceof Object)) {
                return;
            }
            if (!(target instanceof getWindowOf(target).Element)) {
                throw new TypeError('parameter 1 is not of type "Element".');
            }
            var observations = this.observations_;
            // Do nothing if element is already being observed.
            if (observations.has(target)) {
                return;
            }
            observations.set(target, new ResizeObservation(target));
            this.controller_.addObserver(this);
            // Force the update of observations.
            this.controller_.refresh();
        };
        /**
         * Stops observing provided element.
         *
         * @param {Element} target - Element to stop observing.
         * @returns {void}
         */
        ResizeObserverSPI.prototype.unobserve = function (target) {
            if (!arguments.length) {
                throw new TypeError('1 argument required, but only 0 present.');
            }
            // Do nothing if current environment doesn't have the Element interface.
            if (typeof Element === 'undefined' || !(Element instanceof Object)) {
                return;
            }
            if (!(target instanceof getWindowOf(target).Element)) {
                throw new TypeError('parameter 1 is not of type "Element".');
            }
            var observations = this.observations_;
            // Do nothing if element is not being observed.
            if (!observations.has(target)) {
                return;
            }
            observations.delete(target);
            if (!observations.size) {
                this.controller_.removeObserver(this);
            }
        };
        /**
         * Stops observing all elements.
         *
         * @returns {void}
         */
        ResizeObserverSPI.prototype.disconnect = function () {
            this.clearActive();
            this.observations_.clear();
            this.controller_.removeObserver(this);
        };
        /**
         * Collects observation instances the associated element of which has changed
         * it's content rectangle.
         *
         * @returns {void}
         */
        ResizeObserverSPI.prototype.gatherActive = function () {
            var _this = this;
            this.clearActive();
            this.observations_.forEach(function (observation) {
                if (observation.isActive()) {
                    _this.activeObservations_.push(observation);
                }
            });
        };
        /**
         * Invokes initial callback function with a list of ResizeObserverEntry
         * instances collected from active resize observations.
         *
         * @returns {void}
         */
        ResizeObserverSPI.prototype.broadcastActive = function () {
            // Do nothing if observer doesn't have active observations.
            if (!this.hasActive()) {
                return;
            }
            var ctx = this.callbackCtx_;
            // Create ResizeObserverEntry instance for every active observation.
            var entries = this.activeObservations_.map(function (observation) {
                return new ResizeObserverEntry(observation.target, observation.broadcastRect());
            });
            this.callback_.call(ctx, entries, ctx);
            this.clearActive();
        };
        /**
         * Clears the collection of active observations.
         *
         * @returns {void}
         */
        ResizeObserverSPI.prototype.clearActive = function () {
            this.activeObservations_.splice(0);
        };
        /**
         * Tells whether observer has active observations.
         *
         * @returns {boolean}
         */
        ResizeObserverSPI.prototype.hasActive = function () {
            return this.activeObservations_.length > 0;
        };
        return ResizeObserverSPI;
    }());

    // Registry of internal observers. If WeakMap is not available use current shim
    // for the Map collection as it has all required methods and because WeakMap
    // can't be fully polyfilled anyway.
    var observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();
    /**
     * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation
     * exposing only those methods and properties that are defined in the spec.
     */
    var ResizeObserver = /** @class */ (function () {
        /**
         * Creates a new instance of ResizeObserver.
         *
         * @param {ResizeObserverCallback} callback - Callback that is invoked when
         *      dimensions of the observed elements change.
         */
        function ResizeObserver(callback) {
            if (!(this instanceof ResizeObserver)) {
                throw new TypeError('Cannot call a class as a function.');
            }
            if (!arguments.length) {
                throw new TypeError('1 argument required, but only 0 present.');
            }
            var controller = ResizeObserverController.getInstance();
            var observer = new ResizeObserverSPI(callback, controller, this);
            observers.set(this, observer);
        }

        return ResizeObserver;
    }());
    // Expose public methods of ResizeObserver.
    [
        'observe',
        'unobserve',
        'disconnect'
    ].forEach(function (method) {
        ResizeObserver.prototype[method] = function () {
            var _a;
            return (_a = observers.get(this))[method].apply(_a, arguments);
        };
    });

    var index = (function () {
        // Export existing implementation if available.
        if (typeof global$1.ResizeObserver !== 'undefined') {
            return global$1.ResizeObserver;
        }
        return ResizeObserver;
    })();

    var canUseDOM = !!(
        typeof window !== 'undefined' &&
        window.document &&
        window.document.createElement
    );

    var canUseDom = canUseDOM;

    var SimpleBar =
        /*#__PURE__*/
        function () {
            function SimpleBar(element, options) {
                var _this = this;

                _classCallCheck(this, SimpleBar);

                this.onScroll = function () {
                    if (!_this.scrollXTicking) {
                        window.requestAnimationFrame(_this.scrollX);
                        _this.scrollXTicking = true;
                    }

                    if (!_this.scrollYTicking) {
                        window.requestAnimationFrame(_this.scrollY);
                        _this.scrollYTicking = true;
                    }
                };

                this.scrollX = function () {
                    if (_this.axis.x.isOverflowing) {
                        _this.showScrollbar('x');

                        _this.positionScrollbar('x');
                    }

                    _this.scrollXTicking = false;
                };

                this.scrollY = function () {
                    if (_this.axis.y.isOverflowing) {
                        _this.showScrollbar('y');

                        _this.positionScrollbar('y');
                    }

                    _this.scrollYTicking = false;
                };

                this.onMouseEnter = function () {
                    _this.showScrollbar('x');

                    _this.showScrollbar('y');
                };

                this.onMouseMove = function (e) {
                    _this.mouseX = e.clientX;
                    _this.mouseY = e.clientY;

                    if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
                        _this.onMouseMoveForAxis('x');
                    }

                    if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
                        _this.onMouseMoveForAxis('y');
                    }
                };

                this.onMouseLeave = function () {
                    _this.onMouseMove.cancel();

                    if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
                        _this.onMouseLeaveForAxis('x');
                    }

                    if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
                        _this.onMouseLeaveForAxis('y');
                    }

                    _this.mouseX = -1;
                    _this.mouseY = -1;
                };

                this.onWindowResize = function () {
                    // Recalculate scrollbarWidth in case it's a zoom
                    _this.scrollbarWidth = scrollbarWidth();

                    _this.hideNativeScrollbar();
                };

                this.hideScrollbars = function () {
                    _this.axis.x.track.rect = _this.axis.x.track.el.getBoundingClientRect();
                    _this.axis.y.track.rect = _this.axis.y.track.el.getBoundingClientRect();

                    if (!_this.isWithinBounds(_this.axis.y.track.rect)) {
                        _this.axis.y.scrollbar.el.classList.remove(_this.classNames.visible);

                        _this.axis.y.isVisible = false;
                    }

                    if (!_this.isWithinBounds(_this.axis.x.track.rect)) {
                        _this.axis.x.scrollbar.el.classList.remove(_this.classNames.visible);

                        _this.axis.x.isVisible = false;
                    }
                };

                this.onPointerEvent = function (e) {
                    var isWithinBoundsY, isWithinBoundsX;
                    _this.axis.x.scrollbar.rect = _this.axis.x.scrollbar.el.getBoundingClientRect();
                    _this.axis.y.scrollbar.rect = _this.axis.y.scrollbar.el.getBoundingClientRect();

                    if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
                        isWithinBoundsX = _this.isWithinBounds(_this.axis.x.scrollbar.rect);
                    }

                    if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
                        isWithinBoundsY = _this.isWithinBounds(_this.axis.y.scrollbar.rect);
                    } // If any pointer event is called on the scrollbar


                    if (isWithinBoundsY || isWithinBoundsX) {
                        // Preventing the event's default action stops text being
                        // selectable during the drag.
                        e.preventDefault(); // Prevent event leaking

                        e.stopPropagation();

                        if (e.type === 'mousedown') {
                            if (isWithinBoundsY) {
                                _this.onDragStart(e, 'y');
                            }

                            if (isWithinBoundsX) {
                                _this.onDragStart(e, 'x');
                            }
                        }
                    }
                };

                this.drag = function (e) {
                    var eventOffset;
                    var track = _this.axis[_this.draggedAxis].track;
                    var trackSize = track.rect[_this.axis[_this.draggedAxis].sizeAttr];
                    var scrollbar = _this.axis[_this.draggedAxis].scrollbar;
                    e.preventDefault();
                    e.stopPropagation();

                    if (_this.draggedAxis === 'y') {
                        eventOffset = e.pageY;
                    } else {
                        eventOffset = e.pageX;
                    } // Calculate how far the user's mouse is from the top/left of the scrollbar (minus the dragOffset).


                    var dragPos = eventOffset - track.rect[_this.axis[_this.draggedAxis].offsetAttr] - _this.axis[_this.draggedAxis].dragOffset; // Convert the mouse position into a percentage of the scrollbar height/width.

                    var dragPerc = dragPos / track.rect[_this.axis[_this.draggedAxis].sizeAttr]; // Scroll the content by the same percentage.

                    var scrollPos = dragPerc * _this.contentEl[_this.axis[_this.draggedAxis].scrollSizeAttr]; // Fix browsers inconsistency on RTL

                    if (_this.draggedAxis === 'x') {
                        scrollPos = _this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollbarInverted ? scrollPos - (trackSize + scrollbar.size) : scrollPos;
                        scrollPos = _this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollingInverted ? -scrollPos : scrollPos;
                    }

                    _this.contentEl[_this.axis[_this.draggedAxis].scrollOffsetAttr] = scrollPos;
                };

                this.onEndDrag = function (e) {
                    e.preventDefault();
                    e.stopPropagation();
                    document.removeEventListener('mousemove', _this.drag);
                    document.removeEventListener('mouseup', _this.onEndDrag);
                };

                this.el = element;
                this.flashTimeout;
                this.contentEl;
                this.offsetEl;
                this.maskEl;
                this.globalObserver;
                this.mutationObserver;
                this.resizeObserver;
                this.scrollbarWidth;
                this.minScrollbarWidth = 20;
                this.options = _objectSpread({}, SimpleBar.defaultOptions, options);
                this.classNames = _objectSpread({}, SimpleBar.defaultOptions.classNames, this.options.classNames);
                this.isRtl;
                this.axis = {
                    x: {
                        scrollOffsetAttr: 'scrollLeft',
                        sizeAttr: 'width',
                        scrollSizeAttr: 'scrollWidth',
                        offsetAttr: 'left',
                        overflowAttr: 'overflowX',
                        dragOffset: 0,
                        isOverflowing: true,
                        isVisible: false,
                        forceVisible: false,
                        track: {},
                        scrollbar: {}
                    },
                    y: {
                        scrollOffsetAttr: 'scrollTop',
                        sizeAttr: 'height',
                        scrollSizeAttr: 'scrollHeight',
                        offsetAttr: 'top',
                        overflowAttr: 'overflowY',
                        dragOffset: 0,
                        isOverflowing: true,
                        isVisible: false,
                        forceVisible: false,
                        track: {},
                        scrollbar: {}
                    }
                };
                this.recalculate = lodash_throttle(this.recalculate.bind(this), 64);
                this.onMouseMove = lodash_throttle(this.onMouseMove.bind(this), 64);
                this.hideScrollbars = lodash_debounce(this.hideScrollbars.bind(this), this.options.timeout);
                this.onWindowResize = lodash_debounce(this.onWindowResize.bind(this), 64, {
                    leading: true
                });
                SimpleBar.getRtlHelpers = lodash_memoize(SimpleBar.getRtlHelpers); // getContentElement is deprecated

                this.getContentElement = this.getScrollElement;
                this.init();
            }

            /**
             * Static properties
             */

            /**
             * Helper to fix browsers inconsistency on RTL:
             *  - Firefox inverts the scrollbar initial position
             *  - IE11 inverts both scrollbar position and scrolling offset
             * Directly inspired by @KingSora's OverlayScrollbars https://github.com/KingSora/OverlayScrollbars/blob/master/js/OverlayScrollbars.js#L1634
             */


            _createClass(SimpleBar, [{
                key: "init",
                value: function init() {
                    // Save a reference to the instance, so we know this DOM node has already been instancied
                    this.el.SimpleBar = this; // We stop here on server-side

                    if (canUseDom) {
                        this.initDOM();
                        this.scrollbarWidth = scrollbarWidth();
                        this.recalculate();
                        this.initListeners();
                    }
                }
            }, {
                key: "initDOM",
                value: function initDOM() {
                    var _this2 = this;

                    // make sure this element doesn't have the elements yet
                    if (Array.from(this.el.children).filter(function (child) {
                        return child.classList.contains(_this2.classNames.wrapper);
                    }).length) {
                        // assume that element has his DOM already initiated
                        this.wrapperEl = this.el.querySelector(".".concat(this.classNames.wrapper));
                        this.contentEl = this.el.querySelector(".".concat(this.classNames.content));
                        this.offsetEl = this.el.querySelector(".".concat(this.classNames.offset));
                        this.maskEl = this.el.querySelector(".".concat(this.classNames.mask));
                        this.placeholderEl = this.el.querySelector(".".concat(this.classNames.placeholder));
                        this.heightAutoObserverWrapperEl = this.el.querySelector(".".concat(this.classNames.heightAutoObserverWrapperEl));
                        this.heightAutoObserverEl = this.el.querySelector(".".concat(this.classNames.heightAutoObserverEl));
                        this.axis.x.track.el = this.el.querySelector(".".concat(this.classNames.track, ".").concat(this.classNames.horizontal));
                        this.axis.y.track.el = this.el.querySelector(".".concat(this.classNames.track, ".").concat(this.classNames.vertical));
                    } else {
                        // Prepare DOM
                        this.wrapperEl = document.createElement('div');
                        this.contentEl = document.createElement('div');
                        this.offsetEl = document.createElement('div');
                        this.maskEl = document.createElement('div');
                        this.placeholderEl = document.createElement('div');
                        this.heightAutoObserverWrapperEl = document.createElement('div');
                        this.heightAutoObserverEl = document.createElement('div');
                        this.wrapperEl.classList.add(this.classNames.wrapper);
                        this.contentEl.classList.add(this.classNames.content);
                        this.offsetEl.classList.add(this.classNames.offset);
                        this.maskEl.classList.add(this.classNames.mask);
                        this.placeholderEl.classList.add(this.classNames.placeholder);
                        this.heightAutoObserverWrapperEl.classList.add(this.classNames.heightAutoObserverWrapperEl);
                        this.heightAutoObserverEl.classList.add(this.classNames.heightAutoObserverEl);

                        while (this.el.firstChild) {
                            this.contentEl.appendChild(this.el.firstChild);
                        }

                        this.offsetEl.appendChild(this.contentEl);
                        this.maskEl.appendChild(this.offsetEl);
                        this.heightAutoObserverWrapperEl.appendChild(this.heightAutoObserverEl);
                        this.wrapperEl.appendChild(this.heightAutoObserverWrapperEl);
                        this.wrapperEl.appendChild(this.maskEl);
                        this.wrapperEl.appendChild(this.placeholderEl);
                        this.el.appendChild(this.wrapperEl);
                    }

                    if (!this.axis.x.track.el || !this.axis.y.track.el) {
                        var track = document.createElement('div');
                        var scrollbar = document.createElement('div');
                        track.classList.add(this.classNames.track);
                        scrollbar.classList.add(this.classNames.scrollbar);

                        if (!this.options.autoHide) {
                            scrollbar.classList.add(this.classNames.visible);
                        }

                        track.appendChild(scrollbar);
                        this.axis.x.track.el = track.cloneNode(true);
                        this.axis.x.track.el.classList.add(this.classNames.horizontal);
                        this.axis.y.track.el = track.cloneNode(true);
                        this.axis.y.track.el.classList.add(this.classNames.vertical);
                        this.el.appendChild(this.axis.x.track.el);
                        this.el.appendChild(this.axis.y.track.el);
                    }

                    this.axis.x.scrollbar.el = this.axis.x.track.el.querySelector(".".concat(this.classNames.scrollbar));
                    this.axis.y.scrollbar.el = this.axis.y.track.el.querySelector(".".concat(this.classNames.scrollbar));
                    this.el.setAttribute('data-simplebar', 'init');
                }
            }, {
                key: "initListeners",
                value: function initListeners() {
                    var _this3 = this;

                    // Event listeners
                    if (this.options.autoHide) {
                        this.el.addEventListener('mouseenter', this.onMouseEnter);
                    }

                    ['mousedown', 'click', 'dblclick', 'touchstart', 'touchend', 'touchmove'].forEach(function (e) {
                        _this3.el.addEventListener(e, _this3.onPointerEvent, true);
                    });
                    this.el.addEventListener('mousemove', this.onMouseMove);
                    this.el.addEventListener('mouseleave', this.onMouseLeave);
                    this.contentEl.addEventListener('scroll', this.onScroll); // Browser zoom triggers a window resize

                    window.addEventListener('resize', this.onWindowResize); // MutationObserver is IE11+

                    if (typeof MutationObserver !== 'undefined') {
                        // create an observer instance
                        this.mutationObserver = new MutationObserver(function (mutations) {
                            mutations.forEach(function (mutation) {
                                if (mutation.target === _this3.el || !_this3.isChildNode(mutation.target) || mutation.addedNodes.length || mutation.removedNodes.length) {
                                    _this3.recalculate();
                                }
                            });
                        }); // pass in the target node, as well as the observer options

                        this.mutationObserver.observe(this.el, {
                            attributes: true,
                            childList: true,
                            characterData: true,
                            subtree: true
                        });
                    }

                    this.resizeObserver = new index(this.recalculate);
                    this.resizeObserver.observe(this.el);
                }
            }, {
                key: "recalculate",
                value: function recalculate() {
                    var isHeightAuto = this.heightAutoObserverEl.offsetHeight <= 1;
                    this.elStyles = window.getComputedStyle(this.el);
                    this.isRtl = this.elStyles.direction === 'rtl';
                    this.contentEl.style.padding = "".concat(this.elStyles.paddingTop, " ").concat(this.elStyles.paddingRight, " ").concat(this.elStyles.paddingBottom, " ").concat(this.elStyles.paddingLeft);
                    this.contentEl.style.height = isHeightAuto ? 'auto' : '100%';
                    this.placeholderEl.style.width = "".concat(this.contentEl.scrollWidth, "px");
                    this.placeholderEl.style.height = "".concat(this.contentEl.scrollHeight, "px");
                    this.wrapperEl.style.margin = "-".concat(this.elStyles.paddingTop, " -").concat(this.elStyles.paddingRight, " -").concat(this.elStyles.paddingBottom, " -").concat(this.elStyles.paddingLeft);
                    this.axis.x.track.rect = this.axis.x.track.el.getBoundingClientRect();
                    this.axis.y.track.rect = this.axis.y.track.el.getBoundingClientRect(); // Set isOverflowing to false if scrollbar is not necessary (content is shorter than offset)

                    this.axis.x.isOverflowing = (this.scrollbarWidth ? this.contentEl.scrollWidth : this.contentEl.scrollWidth - this.minScrollbarWidth) > Math.ceil(this.axis.x.track.rect.width);
                    this.axis.y.isOverflowing = (this.scrollbarWidth ? this.contentEl.scrollHeight : this.contentEl.scrollHeight - this.minScrollbarWidth) > Math.ceil(this.axis.y.track.rect.height); // Set isOverflowing to false if user explicitely set hidden overflow

                    this.axis.x.isOverflowing = this.elStyles.overflowX === 'hidden' ? false : this.axis.x.isOverflowing;
                    this.axis.y.isOverflowing = this.elStyles.overflowY === 'hidden' ? false : this.axis.y.isOverflowing;
                    this.axis.x.forceVisible = this.options.forceVisible === "x" || this.options.forceVisible === true;
                    this.axis.y.forceVisible = this.options.forceVisible === "y" || this.options.forceVisible === true;
                    this.axis.x.scrollbar.size = this.getScrollbarSize('x');
                    this.axis.y.scrollbar.size = this.getScrollbarSize('y');
                    this.axis.x.scrollbar.el.style.width = "".concat(this.axis.x.scrollbar.size, "px");
                    this.axis.y.scrollbar.el.style.height = "".concat(this.axis.y.scrollbar.size, "px");
                    this.positionScrollbar('x');
                    this.positionScrollbar('y');
                    this.toggleTrackVisibility('x');
                    this.toggleTrackVisibility('y');
                    this.hideNativeScrollbar();
                }
                /**
                 * Calculate scrollbar size
                 */

            }, {
                key: "getScrollbarSize",
                value: function getScrollbarSize() {
                    var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
                    var contentSize = this.scrollbarWidth ? this.contentEl[this.axis[axis].scrollSizeAttr] : this.contentEl[this.axis[axis].scrollSizeAttr] - this.minScrollbarWidth;
                    var trackSize = this.axis[axis].track.rect[this.axis[axis].sizeAttr];
                    var scrollbarSize;

                    if (!this.axis[axis].isOverflowing) {
                        return;
                    }

                    var scrollbarRatio = trackSize / contentSize; // Calculate new height/position of drag handle.

                    scrollbarSize = Math.max(~~(scrollbarRatio * trackSize), this.options.scrollbarMinSize);

                    if (this.options.scrollbarMaxSize) {
                        scrollbarSize = Math.min(scrollbarSize, this.options.scrollbarMaxSize);
                    }

                    return scrollbarSize;
                }
            }, {
                key: "positionScrollbar",
                value: function positionScrollbar() {
                    var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
                    var contentSize = this.contentEl[this.axis[axis].scrollSizeAttr];
                    var trackSize = this.axis[axis].track.rect[this.axis[axis].sizeAttr];
                    var hostSize = parseInt(this.elStyles[this.axis[axis].sizeAttr], 10);
                    var scrollbar = this.axis[axis].scrollbar;
                    var scrollOffset = this.contentEl[this.axis[axis].scrollOffsetAttr];
                    scrollOffset = axis === 'x' && this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollingInverted ? -scrollOffset : scrollOffset;
                    var scrollPourcent = scrollOffset / (contentSize - hostSize);
                    var handleOffset = ~~((trackSize - scrollbar.size) * scrollPourcent);
                    handleOffset = axis === 'x' && this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollbarInverted ? handleOffset + (trackSize - scrollbar.size) : handleOffset;
                    scrollbar.el.style.transform = axis === 'x' ? "translate3d(".concat(handleOffset, "px, 0, 0)") : "translate3d(0, ".concat(handleOffset, "px, 0)");
                }
            }, {
                key: "toggleTrackVisibility",
                value: function toggleTrackVisibility() {
                    var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
                    var track = this.axis[axis].track.el;
                    var scrollbar = this.axis[axis].scrollbar.el;

                    if (this.axis[axis].isOverflowing || this.axis[axis].forceVisible) {
                        track.style.visibility = 'visible';
                        this.contentEl.style[this.axis[axis].overflowAttr] = 'scroll';
                    } else {
                        track.style.visibility = 'hidden';
                        this.contentEl.style[this.axis[axis].overflowAttr] = 'hidden';
                    } // Even if forceVisible is enabled, scrollbar itself should be hidden


                    if (this.axis[axis].isOverflowing) {
                        scrollbar.style.visibility = 'visible';
                    } else {
                        scrollbar.style.visibility = 'hidden';
                    }
                }
            }, {
                key: "hideNativeScrollbar",
                value: function hideNativeScrollbar() {
                    this.offsetEl.style[this.isRtl ? 'left' : 'right'] = this.axis.y.isOverflowing || this.axis.y.forceVisible ? "-".concat(this.scrollbarWidth || this.minScrollbarWidth, "px") : 0;
                    this.offsetEl.style.bottom = this.axis.x.isOverflowing || this.axis.x.forceVisible ? "-".concat(this.scrollbarWidth || this.minScrollbarWidth, "px") : 0; // If floating scrollbar

                    if (!this.scrollbarWidth) {
                        var paddingDirection = [this.isRtl ? 'paddingLeft' : 'paddingRight'];
                        this.contentEl.style[paddingDirection] = this.axis.y.isOverflowing || this.axis.y.forceVisible ? "calc(".concat(this.elStyles[paddingDirection], " + ").concat(this.minScrollbarWidth, "px)") : this.elStyles[paddingDirection];
                        this.contentEl.style.paddingBottom = this.axis.x.isOverflowing || this.axis.x.forceVisible ? "calc(".concat(this.elStyles.paddingBottom, " + ").concat(this.minScrollbarWidth, "px)") : this.elStyles.paddingBottom;
                    }
                }
                /**
                 * On scroll event handling
                 */

            }, {
                key: "onMouseMoveForAxis",
                value: function onMouseMoveForAxis() {
                    var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
                    this.axis[axis].track.rect = this.axis[axis].track.el.getBoundingClientRect();
                    this.axis[axis].scrollbar.rect = this.axis[axis].scrollbar.el.getBoundingClientRect();
                    var isWithinScrollbarBoundsX = this.isWithinBounds(this.axis[axis].scrollbar.rect);

                    if (isWithinScrollbarBoundsX) {
                        this.axis[axis].scrollbar.el.classList.add(this.classNames.hover);
                    } else {
                        this.axis[axis].scrollbar.el.classList.remove(this.classNames.hover);
                    }

                    if (this.isWithinBounds(this.axis[axis].track.rect)) {
                        this.showScrollbar(axis);
                        this.axis[axis].track.el.classList.add(this.classNames.hover);
                    } else {
                        this.axis[axis].track.el.classList.remove(this.classNames.hover);
                    }
                }
            }, {
                key: "onMouseLeaveForAxis",
                value: function onMouseLeaveForAxis() {
                    var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
                    this.axis[axis].track.el.classList.remove(this.classNames.hover);
                    this.axis[axis].scrollbar.el.classList.remove(this.classNames.hover);
                }
            }, {
                key: "showScrollbar",

                /**
                 * Show scrollbar
                 */
                value: function showScrollbar() {
                    var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
                    var scrollbar = this.axis[axis].scrollbar.el;

                    if (!this.axis[axis].isVisible) {
                        scrollbar.classList.add(this.classNames.visible);
                        this.axis[axis].isVisible = true;
                    }

                    if (this.options.autoHide) {
                        this.hideScrollbars();
                    }
                }
                /**
                 * Hide Scrollbar
                 */

            }, {
                key: "onDragStart",

                /**
                 * on scrollbar handle drag movement starts
                 */
                value: function onDragStart(e) {
                    var axis = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'y';
                    var scrollbar = this.axis[axis].scrollbar.el; // Measure how far the user's mouse is from the top of the scrollbar drag handle.

                    var eventOffset = axis === 'y' ? e.pageY : e.pageX;
                    this.axis[axis].dragOffset = eventOffset - scrollbar.getBoundingClientRect()[this.axis[axis].offsetAttr];
                    this.draggedAxis = axis;
                    document.addEventListener('mousemove', this.drag);
                    document.addEventListener('mouseup', this.onEndDrag);
                }
                /**
                 * Drag scrollbar handle
                 */

            }, {
                key: "getScrollElement",

                /**
                 * Getter for original scrolling element
                 */
                value: function getScrollElement() {
                    return this.contentEl;
                }
            }, {
                key: "removeListeners",
                value: function removeListeners() {
                    var _this4 = this;

                    // Event listeners
                    if (this.options.autoHide) {
                        this.el.removeEventListener('mouseenter', this.onMouseEnter);
                    }

                    ['mousedown', 'click', 'dblclick', 'touchstart', 'touchend', 'touchmove'].forEach(function (e) {
                        _this4.el.removeEventListener(e, _this4.onPointerEvent);
                    });
                    this.el.removeEventListener('mousemove', this.onMouseMove);
                    this.el.removeEventListener('mouseleave', this.onMouseLeave);
                    this.contentEl.removeEventListener('scroll', this.onScroll);
                    window.removeEventListener('resize', this.onWindowResize);
                    this.mutationObserver && this.mutationObserver.disconnect();
                    this.resizeObserver.disconnect(); // Cancel all debounced functions

                    this.recalculate.cancel();
                    this.onMouseMove.cancel();
                    this.hideScrollbars.cancel();
                    this.onWindowResize.cancel();
                }
                /**
                 * UnMount mutation observer and delete SimpleBar instance from DOM element
                 */

            }, {
                key: "unMount",
                value: function unMount() {
                    this.removeListeners();
                    this.el.SimpleBar = null;
                }
                /**
                 * Recursively walks up the parent nodes looking for this.el
                 */

            }, {
                key: "isChildNode",
                value: function isChildNode(el) {
                    if (el === null) return false;
                    if (el === this.el) return true;
                    return this.isChildNode(el.parentNode);
                }
                /**
                 * Check if mouse is within bounds
                 */

            }, {
                key: "isWithinBounds",
                value: function isWithinBounds(bbox) {
                    return this.mouseX >= bbox.left && this.mouseX <= bbox.left + bbox.width && this.mouseY >= bbox.top && this.mouseY <= bbox.top + bbox.height;
                }
            }], [{
                key: "getRtlHelpers",
                value: function getRtlHelpers() {
                    var dummyDiv = document.createElement('div');
                    dummyDiv.innerHTML = '<div class="hs-dummy-scrollbar-size"><div style="height: 200%; width: 200%; margin: 10px 0;"></div></div>';
                    var scrollbarDummyEl = dummyDiv.firstElementChild;
                    document.body.appendChild(scrollbarDummyEl);
                    var dummyContainerChild = scrollbarDummyEl.firstElementChild;
                    scrollbarDummyEl.scrollLeft = 0;
                    var dummyContainerOffset = SimpleBar.getOffset(scrollbarDummyEl);
                    var dummyContainerChildOffset = SimpleBar.getOffset(dummyContainerChild);
                    scrollbarDummyEl.scrollLeft = 999;
                    var dummyContainerScrollOffsetAfterScroll = SimpleBar.getOffset(dummyContainerChild);
                    return {
                        // determines if the scrolling is responding with negative values
                        isRtlScrollingInverted: dummyContainerOffset.left !== dummyContainerChildOffset.left && dummyContainerChildOffset.left - dummyContainerScrollOffsetAfterScroll.left !== 0,
                        // determines if the origin scrollbar position is inverted or not (positioned on left or right)
                        isRtlScrollbarInverted: dummyContainerOffset.left !== dummyContainerChildOffset.left
                    };
                }
            }, {
                key: "initHtmlApi",
                value: function initHtmlApi() {
                    this.initDOMLoadedElements = this.initDOMLoadedElements.bind(this); // MutationObserver is IE11+

                    if (typeof MutationObserver !== 'undefined') {
                        // Mutation observer to observe dynamically added elements
                        this.globalObserver = new MutationObserver(function (mutations) {
                            mutations.forEach(function (mutation) {
                                Array.from(mutation.addedNodes).forEach(function (addedNode) {
                                    if (addedNode.nodeType === 1) {
                                        if (addedNode.hasAttribute('data-simplebar')) {
                                            !addedNode.SimpleBar && new SimpleBar(addedNode, SimpleBar.getElOptions(addedNode));
                                        } else {
                                            Array.from(addedNode.querySelectorAll('[data-simplebar]')).forEach(function (el) {
                                                !el.SimpleBar && new SimpleBar(el, SimpleBar.getElOptions(el));
                                            });
                                        }
                                    }
                                });
                                Array.from(mutation.removedNodes).forEach(function (removedNode) {
                                    if (removedNode.nodeType === 1) {
                                        if (removedNode.hasAttribute('data-simplebar')) {
                                            removedNode.SimpleBar && removedNode.SimpleBar.unMount();
                                        } else {
                                            Array.from(removedNode.querySelectorAll('[data-simplebar]')).forEach(function (el) {
                                                el.SimpleBar && el.SimpleBar.unMount();
                                            });
                                        }
                                    }
                                });
                            });
                        });
                        this.globalObserver.observe(document, {
                            childList: true,
                            subtree: true
                        });
                    } // Taken from jQuery `ready` function
                    // Instantiate elements already present on the page


                    if (document.readyState === 'complete' || document.readyState !== 'loading' && !document.documentElement.doScroll) {
                        // Handle it asynchronously to allow scripts the opportunity to delay init
                        window.setTimeout(this.initDOMLoadedElements);
                    } else {
                        document.addEventListener('DOMContentLoaded', this.initDOMLoadedElements);
                        window.addEventListener('load', this.initDOMLoadedElements);
                    }
                } // Helper function to retrieve options from element attributes

            }, {
                key: "getElOptions",
                value: function getElOptions(el) {
                    var options = Array.from(el.attributes).reduce(function (acc, attribute) {
                        var option = attribute.name.match(/data-simplebar-(.+)/);

                        if (option) {
                            var key = option[1].replace(/\W+(.)/g, function (x, chr) {
                                return chr.toUpperCase();
                            });

                            switch (attribute.value) {
                                case 'true':
                                    acc[key] = true;
                                    break;

                                case 'false':
                                    acc[key] = false;
                                    break;

                                case undefined:
                                    acc[key] = true;
                                    break;

                                default:
                                    acc[key] = attribute.value;
                            }
                        }

                        return acc;
                    }, {});
                    return options;
                }
            }, {
                key: "removeObserver",
                value: function removeObserver() {
                    this.globalObserver.disconnect();
                }
            }, {
                key: "initDOMLoadedElements",
                value: function initDOMLoadedElements() {
                    document.removeEventListener('DOMContentLoaded', this.initDOMLoadedElements);
                    window.removeEventListener('load', this.initDOMLoadedElements);
                    Array.from(document.querySelectorAll('[data-simplebar]')).forEach(function (el) {
                        if (!el.SimpleBar) new SimpleBar(el, SimpleBar.getElOptions(el));
                    });
                }
            }, {
                key: "getOffset",
                value: function getOffset(el) {
                    var rect = el.getBoundingClientRect();
                    return {
                        top: rect.top + (window.pageYOffset || document.documentElement.scrollTop),
                        left: rect.left + (window.pageXOffset || document.documentElement.scrollLeft)
                    };
                }
            }]);

            return SimpleBar;
        }();
    /**
     * HTML API
     * Called only in a browser env.
     */


    SimpleBar.defaultOptions = {
        autoHide: true,
        forceVisible: false,
        classNames: {
            content: 'simplebar-content',
            offset: 'simplebar-offset',
            mask: 'simplebar-mask',
            wrapper: 'simplebar-wrapper',
            placeholder: 'simplebar-placeholder',
            scrollbar: 'simplebar-scrollbar',
            track: 'simplebar-track',
            heightAutoObserverWrapperEl: 'simplebar-height-auto-observer-wrapper',
            heightAutoObserverEl: 'simplebar-height-auto-observer',
            visible: 'simplebar-visible',
            horizontal: 'simplebar-horizontal',
            vertical: 'simplebar-vertical',
            hover: 'simplebar-hover'
        },
        scrollbarMinSize: 25,
        scrollbarMaxSize: 0,
        timeout: 1000
    };

    if (canUseDom) {
        SimpleBar.initHtmlApi();
    }

    return SimpleBar;

}));
